Bulduğum şeyler üzerinde çoklu komut çalıştırmaya çalışıyorum, bunu nasıl başarabilirim?
find . -exec cmd1; cmd2
işe görünmüyor; bunun yerine her dosyada cmd1 çalıştırıldıktan sonra cmd2'yi çalıştırır.
Bulduğum şeyler üzerinde çoklu komut çalıştırmaya çalışıyorum, bunu nasıl başarabilirim?
find . -exec cmd1; cmd2
işe görünmüyor; bunun yerine her dosyada cmd1 çalıştırıldıktan sonra cmd2'yi çalıştırır.
Yanıtlar:
Bu gösteride ilk önce sh -c 'echo first; false'
(veya true
) kullanacağım -exec
. Bu, bazı çıktılar verecek ve ayrıca seçilen çıkış kodu efektine sahip olacaktır. Sonra echo second
ikincisi için kullanılacak. Geçerli dizinde bir dosya olduğunu varsayalım.
$ 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
Bu tür gerçek bir komut şöyle görünür:
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
İkinci sette, kaçan parantezler iki -exec
maddeyi gruplandırır . Bunlar -false
arasında test durumu "yanlış" olmaya zorlar ve bir -o
sonraki ifadenin (ikincisi -exec
) nedeniyle değerlendirilmesine neden olur -false
.
Kimden man find
:
expr1 expr2
Bir satırdaki iki ifade, ima edilen "ve"; ifade1 yanlış ise ifade2 değerlendirilmez.ifade1 -a ifade2 ifade1 ifade1 ile
aynıdır.ifade1 -o ifade2
ya da; ifade1 doğruysa ifade2 değerlendirilmez.
Cmd1'in hata kodu nedeniyle cmd2'nin çalışmasını engelleyememesi önemli değilse 0
:
find . -exec cmd1 \; -exec cmd2 \;
Her iki komutu da her zaman çalıştırmanın tek güvenilir yolu find
, daha sonra komutları sırayla çalıştıracak bir kabuk çağırmaktır:
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Eğer cmd1 ve cmd2'yi yapan bir betik hazırlamanın sakıncası yoksa, o zaman işte bu:
find . -exec myscript {} \;
veya
find . -exec myscript {} +
Kullanın \; veya +, myscript'in bir kerede birden fazla dosyayı işleyip işlemeyebileceğine bağlı olarak (dosya adlarında boşluk varsa vb.
Yaptıklarını bir senaryoya koymak, deneyimlerime göre, neredeyse her zaman buna değdi. Bir kez yapmak zorunda kalırsan, tekrar yapmak zorunda kalacaksın.
Ancak bulmacayı betiğin içine koymak için düzgün bir numara :
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Daha sonra myscript üzerinde çalışması için argüman olarak verdiğiniz dosyalar üzerinde çalışır, ancak herhangi bir argüman vermezseniz, geçerli dizinden bulmayı çalıştırır ve ardından bulunan dosyalar üzerinde kendisini çağırır. Bu, -exec'in betiğinizde tanımladığınız kabuk işlevlerini çağıramayacağı gerçeğini ortaya çıkarır.
Eskiden her iki çözümü de çok şanssız deniyorum. Bu benim için iyi çalıştı:
$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done
komutunu deneyin:
sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l
*
İçinde -exec
kısmen geçerli dizindeki tüm dosyalara genişleyecektir. Özellikle olarak çalışırken sudo
.
-o
.