Một -exec
lệnh phải được chấm dứt bằng một ;
(vì vậy bạn thường cần phải gõ \;
hoặc ';'
để tránh sự diễn giải bằng vỏ) hoặc a +
. Sự khác biệt là với ;
lệnh được gọi một lần cho mỗi tệp, với +
, nó được gọi càng ít lần càng tốt (thường là một lần, nhưng có độ dài tối đa cho một dòng lệnh, vì vậy nó có thể được tách ra) với tất cả tên tệp . Xem ví dụ này:
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
Lệnh của bạn có hai lỗi:
Đầu tiên, bạn sử dụng {};
, nhưng ;
phải là một tham số của riêng nó.
Thứ hai, lệnh kết thúc tại &&
. Bạn đã chỉ định chạy run find và nếu thành công, hãy xóa tệp có tên {};
.. Nếu bạn muốn sử dụng shell shell trong -exec
lệnh, bạn cần chạy nó một cách rõ ràng trong shell, chẳng hạn như -exec sh -c 'ffmpeg ... && rm'
.
Tuy nhiên, bạn không nên thêm {} bên trong lệnh bash, nó sẽ tạo ra vấn đề khi có các ký tự đặc biệt. Thay vào đó, bạn có thể vượt qua các thông số bổ sung cho vỏ sau -c command_string
(xem man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Bạn thấy $
điều được đánh giá bởi shell trong ví dụ đầu tiên. Hãy tưởng tượng có một tập tin gọi là $(rm -rf /)
:-)
(Lưu ý bên: -
Không cần thiết, nhưng biến đầu tiên sau khi lệnh được gán cho biến $0
, đây là biến đặc biệt thường chứa tên của chương trình đang chạy và đặt tham số đó là một ô uế, mặc dù nó đã thắng Có thể không gây ra bất kỳ tác hại nào ở đây, vì vậy chúng tôi đặt nó thành -
và bắt đầu với $1
.)
Vì vậy, lệnh của bạn có thể là một cái gì đó như
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Nhưng có một cách tốt hơn. tìm hỗ trợ and
và or
, vì vậy bạn có thể làm những thứ như find -name foo -or -name bar
. Nhưng điều đó cũng hoạt động với -exec
, đánh giá là đúng nếu lệnh thoát thành công và sai nếu không. Xem ví dụ này:
$ ls
false true
$ find * -exec {} \; -and -print
true
Nó chỉ chạy bản in nếu lệnh thành công, nó đã làm true
nhưng không làm false
.
Vì vậy, bạn có thể sử dụng hai câu lệnh exec được xâu chuỗi với một -and
và nó sẽ chỉ thực hiện câu lệnh sau nếu câu lệnh trước được chạy thành công.