Sebuah -exec
perintah harus diakhiri dengan ;
(sehingga Anda biasanya perlu mengetik \;
atau ';'
untuk menghindari interpretion oleh shell) atau +
. Perbedaannya adalah bahwa dengan ;
, perintah dipanggil sekali per file, dengan +
, ia dipanggil beberapa kali mungkin (biasanya sekali, tetapi ada panjang maksimum untuk baris perintah, sehingga mungkin terpecah) dengan semua nama file . Lihat contoh ini:
$ 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
Perintah Anda memiliki dua kesalahan:
Pertama, Anda menggunakan {};
, tetapi ;
harus menjadi parameter sendiri.
Kedua, perintah berakhir di &&
. Anda menentukan "run find, dan jika itu berhasil, hapus file bernama {};
.". Jika Anda ingin menggunakan shell stuff di -exec
perintah, Anda perlu menjalankannya secara eksplisit di shell, seperti -exec sh -c 'ffmpeg ... && rm'
.
Namun Anda tidak boleh menambahkan {} di dalam perintah bash, itu akan menghasilkan masalah ketika ada karakter khusus. Sebagai gantinya, Anda dapat meneruskan parameter tambahan ke shell setelah -c command_string
(lihat man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Anda melihat $
hal dievaluasi oleh shell pada contoh pertama. Bayangkan ada file bernama $(rm -rf /)
:-)
(Catatan: Ini -
tidak diperlukan, tetapi variabel pertama setelah perintah ditugaskan ke variabel $0
, yang merupakan variabel khusus yang biasanya berisi nama program yang sedang dijalankan dan menetapkan bahwa ke parameter sedikit najis, meskipun ia menang mungkin menyebabkan kerusakan apa pun di sini, jadi kami mengaturnya agar adil -
dan mulai dengan $1
.)
Jadi perintahmu bisa seperti itu
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Tetapi ada cara yang lebih baik. menemukan dukungan and
dan or
, jadi Anda dapat melakukan hal-hal seperti find -name foo -or -name bar
. Tapi itu juga bekerja dengan -exec
, yang bernilai true jika perintah berhasil keluar, dan false jika tidak. Lihat contoh ini:
$ ls
false true
$ find * -exec {} \; -and -print
true
Hanya menjalankan cetakan jika perintah berhasil, yang dilakukan untuk true
tetapi tidak untuk false
.
Jadi, Anda dapat menggunakan dua pernyataan exec yang dirantai dengan -and
, dan itu hanya akan mengeksekusi yang kedua jika yang pertama dijalankan dengan sukses.