Saya mencoba menjalankan beberapa perintah pada hal-hal yang saya temukan, bagaimana saya bisa mencapai ini?
find . -exec cmd1; cmd2
sepertinya tidak berfungsi; itu malah menjalankan cmd2 setelah cmd1 telah dieksekusi pada setiap file.
Saya mencoba menjalankan beberapa perintah pada hal-hal yang saya temukan, bagaimana saya bisa mencapai ini?
find . -exec cmd1; cmd2
sepertinya tidak berfungsi; itu malah menjalankan cmd2 setelah cmd1 telah dieksekusi pada setiap file.
Jawaban:
Dalam demonstrasi ini, saya akan menggunakan sh -c 'echo first; false'
(atau true
) untuk yang pertama -exec
. Itu akan memberikan beberapa output dan juga memiliki efek kode keluar yang dipilih. Kemudian echo second
akan digunakan untuk yang kedua. Asumsikan ada satu file di direktori saat ini.
$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
Perintah nyata dari jenis ini akan terlihat seperti:
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
Pada set kedua, tanda kurung yang lolos mengelompokkan dua -exec
klausa. Di -false
antara mereka memaksa negara uji untuk "salah" dan -o
menyebabkan ekspresi selanjutnya (yang kedua -exec
) dievaluasi karena -false
.
Dari man find
:
expr1 expr2
Dua ekspresi berturut-turut diambil untuk digabungkan dengan tersirat "dan"; expr2 tidak dievaluasi jika expr1 salah.expr1 -a expr2
Sama seperti expr1 expr2.expr1 -o expr2
Atau; expr2 tidak dievaluasi jika expr1 benar.
Jika Anda tidak peduli tentang cmd1 dapat mencegah cmd2 dijalankan karena kode kesalahan 0
:
find . -exec cmd1 \; -exec cmd2 \;
Satu-satunya cara yang dapat diandalkan untuk mendapatkan kedua perintah untuk selalu menjalankan ini adalah dengan find
memanggil shell yang selanjutnya akan menjalankan perintah secara berurutan:
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Jika Anda tidak keberatan membuat skrip yang memiliki cmd1 dan cmd2, maka cukup ini:
find . -exec myscript {} \;
atau
find . -exec myscript {} +
Gunakan \; atau + tergantung pada apakah skrip saya dapat menangani lebih dari satu file pada satu waktu (menjadi berbulu jika ada spasi dalam nama file, dll).
Menempatkan apa yang Anda lakukan dalam sebuah skrip, dalam pengalaman saya, hampir selalu sepadan. Jika Anda harus melakukannya sekali, Anda harus melakukannya lagi.
Tetapi trik yang rapi adalah dengan menempatkan temuan di dalam skrip:
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Kemudian myscript bekerja pada file apa pun yang Anda berikan sebagai argumen agar bisa berfungsi, tetapi jika Anda tidak memberikan argumen apa pun, itu berjalan temukan dari dir saat ini, dan kemudian menyebut dirinya pada file yang ditemukan. Ini mengatasi fakta bahwa -exec tidak dapat memanggil fungsi shell yang telah Anda tetapkan dalam skrip Anda.
Saya telah mencoba kedua solusi sebelumnya tanpa banyak keberuntungan. Yang ini bekerja dengan baik untuk saya:
$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done
coba perintah:
sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l
*
di -exec
bagian akan diperluas untuk semua file dalam direktori saat ini. Terutama saat menjalankan sebagai sudo
.
-o
.