find
İlk eşleşmeyi bulduktan hemen sonra komutu durdurmaya zorlamanın bir yolu var mı ?
find
İlk eşleşmeyi bulduktan hemen sonra komutu durdurmaya zorlamanın bir yolu var mı ?
Yanıtlar:
GNU veya FreeBSD ile find
, -quit
yüklemeyi kullanabilirsiniz :
find . ... -print -quit
NetBSD find
eşdeğeri:
find . ... -print -exit
Tek yapmanız gereken adı yazdırmaksa ve dosya adlarının yeni satır karakterleri içermediğini varsayarsanız, şunları yapabilirsiniz:
find . ... -print | head -n 1
Bu find
ilk maçtan sonra durmayacak , ancak muhtemelen ikinci maçta zamanlamaya ve tamponlamaya bağlı olarak veya (daha sonra) duracaktır . Temel olarak, find
önceden girilmiş olan bir şeyi çıkarmaya çalıştığında SIGPIPE ile sonlandırılacak head
çünkü zaten girişin ilk satırını okudu ve görüntüledi.
Döndükten find
sonra tüm mermilerin bu komutu beklemeyeceğini unutmayın head
. Bourne kabuğu ve AT&T ksh
(etkileşimli olmadığında) ve yash
(yalnızca bu satırsonu komut dosyasındaki son komut ise) uygulamaları arka planda çalışmaya devam etmeyecektir. Bu davranışı herhangi bir kabukta görmek isterseniz, yukarıdakileri istediğiniz zaman değiştirebilirsiniz:
(find . ... -print &) | head -n 1
Bulunan dosyaların yollarını yazdırmaktan daha fazlasını yapıyorsanız, bu yaklaşımı deneyebilirsiniz:
find . ... -exec sh -c 'printf "%s\n" "$1"; kill "$PPID"' sh {} \;
( printf
bu dosya ile ne yaparsanız yapın ile değiştirin ).
Bu, find
ancak öldürüldüğü gerçeğini yansıtan bir çıkış statüsü döndürmenin yan etkisine sahiptir .
Aslında, SIGTERM yerine SIGPIPE sinyalinin kullanılması ( kill -s PIPE
yerine kill
), bazı kabukların bu ölüm konusunda daha sessiz olmasına neden olur (ancak yine de sıfır olmayan bir çıkış durumu döndürür).
if [[ $(find ... -print -quit) ]]; then ...
Basılı herhangi bir şeyin basılı olup olmadığını test eder.
$(…)
Sadece tek parantez ( [ … ]
) kullanıyorsanız , parçayı tırnak içine almak daha iyidir .
[
standart bir komuttur. O kadar korkunç bir komut değil, Bourne benzeri mermiler komut satırlarını ayrıştırıyor. [[...]]
çeşitli mermilerde kendine ait sorunları olan bir ksh yapısıdır. Örneğin, yakın zamana kadar [[ $(...) ]]
işe yaramadı zsh
(ihtiyacınız vardı [[ -n $(...) ]]
). Bunun dışında zsh
, alıntılara ihtiyacınız var [[ $a = $b ]]
, [[ =~ ]]
uygulamalar arasında ve hatta bash sürümleri ile bazılarında birkaç hata arasında uyumsuz farklılıklar var. Şahsen ben tercih ederim [
.
...
? .
find . -name something -print -quit
Yazdırdıktan sonra ilk eşleşmeden sonra bulmayı sonlandırır.
Belirli bir miktarda eşleşmeden sonra bulguyu sonlandır ve sonuçları yazdır:
find . -name something -print | head -n 5
Şaşırtıcı bir şekilde - baş şimdi 5 kibrin sonunda ipi sonlandırıyor, ancak nasıl veya neden olduğunu bilmiyorum.
Test etmek çok kolaydır. En az bir dakika veya daha uzun sürerken binlerce, belki daha da fazla eşleşmeye neden olacak bir kök üzerinde arama yapalım . Ancak "head" ("head") içine yerleştirildiğinde , head içinde tanımlanmış olan belirli sayıda satırdan sonra sonlanacaktır (varsayılan head 10 gösterir, satırları belirtmek için "head -n" kullanın).
"Headn", belirtilen newline karakter sayısına ulaştığında sona ereceğini ve bu nedenle birden fazla newline karakteri içeren eşleşmelerin buna göre sayılacağını unutmayın.
Eğlence amaçlı, işte Bash'ta tembel bir jeneratör bul. Bu örnek, geçerli dizindeki dosyalar üzerinde bir halka oluşturur. İstediğin kadarını oku o zaman kill %+
(belki sadece 1)
#!/usr/bin/env bash
unset -v files n
trap 'kill "$x_PID"' EXIT
coproc x while :; do
find . -type f -maxdepth 1 -exec sh -c "$(</dev/fd/3)" _ {} +
done 4<&0 <<\EOF 3<&0 <&4-
for x; do
read -r _
printf '%s\0' "$x"
done
EOF
while
echo >&${x[1]}
IFS= read -rd '' -u "$x" 'files[n++]'
do
printf '%q ' "${files[@]}"
echo
sleep .2
done
grep, bayrakla birlikte kullanıldığında -m
da
find stuff | grep -m1 .
Find tarafından basılan ilk satırdan sonra geri dönecektir.
Bunun arasındaki fark find stuff -print -quit | head -1
, eğer arama yeterince hızlıysa grep, süreci zaman içinde durduramayabilir (gerçekten de farketmez), arama uzunsa bile, gerekmediği kadar çok baskı almak için yedek bulunacaktır. çizgiler.
busybox grep de buna sahip -m
olmadığından, bunun yerine busybox find ile çalışır
find /tmp/stuff -exec "sh" "-c" "eval 'echo {}; { kill \$PPID; }'" \;
bu, (genellikle) sigterm sinyalini alan bulma işlemi hakkında bir mesaj verir, ancak bu çıktı, çalışan kabuğa aittir, bu komut, komut satırına karışmaz, bu nedenle komut satırına veya satırların çıktısını alır. Bulmakla eşleşti.