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.
-and
dan-or
tidak portabel. POSIX menentukan-a
dan-o
, dan pada kenyataannya-a
selalu diasumsikan (karenanya tidak diperlukan)."\;"
tidak bekerja tetapi" \;"
tidakSaya menemukan jawabannya sekarang. Ketika Anda perlu menjalankan dua perintah di exec dalam menemukan Anda harus benar-benar memiliki dua eksekutif terpisah. Ini akhirnya berhasil untuk saya.
sumber
echo
sebelum perintah dan lihat apa fungsinya.echo
sangat tidak bisa diandalkan - Anda tidak bisa membedakan antaraecho "one argument"
danecho one argument
(output yang terakhir menjadi salah, karena sebenarnya melewatiecho
dua argumen yang sepenuhnya terpisah). Jauh lebih baik untuk melakukan sesuatu seperti-exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n'
, yang akan mencetak keluaran dengan cara yang membuat karakter yang tidak dapat dicetak terlihat sehingga Anda dapat mendeteksi baris baru DOS dan keanehan lainnya.Coba beri spasi sebelum masing-masing \;
Bekerja:
Tidak bekerja:
sumber
Sekadar informasi Anda:
Saya baru saja mencoba menggunakan perintah "find -exec" pada sistem Cygwin (UNIX diemulasikan pada Windows), dan tampaknya backslash sebelum tanda titik koma harus dihapus:
find ./ -name "blabla" -exec wc -l {} ;
sumber
find /etc/nginx -name '*.conf' -exec echo {} ;
danfind /etc/nginx -name '*.conf' -exec echo {}\;
memberikan hasil yang sama. :({}
.Untuk berjaga-jaga kalau-kalau ada yang melihat "argumen -exec yang hilang" di skrip bash Amazon Opsworks Chef, saya perlu menambahkan backslash lain untuk keluar dari \;
sumber
Juga, jika ada orang lain yang memiliki "find: missing argumen to -exec" ini mungkin membantu:
Dalam beberapa shell Anda tidak perlu melakukan pelolosan, yaitu Anda tidak memerlukan "\" di depan ";".
sumber
;
dikutip atau melarikan diri di sini berarti dapat dikonsumsi oleh shell, tidak dibaca olehfind
. Juga,-f
dan- f
ada dua hal yang berbeda.Anda perlu melakukan beberapa pelarian saya pikir.
sumber
{} Dan && akan menyebabkan masalah karena diperluas oleh baris perintah. Saya sarankan mencoba:
sumber
{}
variabel untuk menghapus file yang tepat?{}
mengembangkan thinik ? Kecuali itu mengandung dua titik atau koma yang akan tetap seperti itu.Anda harus memberi jarak antara
{}
dan\;
Jadi perintahnya akan seperti:
sumber
Jika Anda masih mendapatkan "find: missing argumen to -exec" coba balas argumen eksekusi dengan tanda kutip.
sumber