İlk eşleşmeden sonra find komutunu nasıl durdurabilirim?


131

findİlk eşleşmeyi bulduktan hemen sonra komutu durdurmaya zorlamanın bir yolu var mı ?


4
Thensen: Beşinci kafaya bağlanırken beş sonuçtan sonra bırakmasının nedeni, beş sonuçtan sonra kafanın çıkmasıdır. Kafa çıktığında boru kapanır ve program borularına sonlandırmak için ona bir sinyal gönderir. Doğrudan size cevap vermediğim için üzgünüm, görünüşe göre cevaplamak için 50 itibara ihtiyacınız var.
Ruste

Yanıtlar:


148

GNU veya FreeBSD ile find, -quityüklemeyi kullanabilirsiniz :

find . ... -print -quit

NetBSD findeş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 findilk 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 findsonra 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 {} \;

( printfbu dosya ile ne yaparsanız yapın ile değiştirin ).

Bu, findancak ö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 PIPEyerine 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).


3
Herhangi birinin herhangi bir dosyanın yüklemeyle eşleşip eşleşmediğini test etmesi gerekiyorsa, en kısa sürede durdurulur, Bash ve GNU Find'da yapabilecekleriniz: if [[ $(find ... -print -quit) ]]; then ...Basılı herhangi bir şeyin basılı olup olmadığını test eder.
Tobia,

@Tobia $(…)Sadece tek parantez ( [ … ]) kullanıyorsanız , parçayı tırnak içine almak daha iyidir .
phk

@ phk hariç Tek parantez kullanmıyorum (çünkü korkunçlar) bu yüzden tırnak kullanmama gerek yok.
Tobia,

2
@ Tobia, [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 [.
Stéphane Chazelas,

nedir ...? .
kyb

11
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.


Bu 'programın çıktısı bittikten sonra bittiği' fenomenini de gözlemledim, ancak kabuklarda tutarlı bir şekilde değil. Bence bu kendi sorusunu hak ediyor - neyse ki cevap bash için zaten StackOverflow's Bash: bash betiği ile Head & Tail davranışı . Bu, programın arka planda sonlandırılmasının veya yürütülmesinin devam etmesinin, SIGPIPE'e verdiği yanıtın sonucuna bağlı olduğuna karar vermem için yeterli bilgi verir - öldürme varsayılandır.
adaçayı

'Üzerinde * programlar * / kabukları' demek istedim, ama görünüşe göre unix.stackexchange.com bunu ilk yorumumu düzenlememe izin vermek yerine ikinci bir yorum olarak kaydetmeyi tercih ederdi (bu bir yığın değişikliği, siteye özgü politika kararıdır). Ayrıca, @Ruste'nin bu etki için en üstte yorumda bulunduğunu görüyorum, bu da doğrudan cevaplara gittiğimden beri başlangıçta bana yardımcı olmadı ...
adaçayı

2

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

1

grep, bayrakla birlikte kullanıldığında -mda

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 -molmadığı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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.