पहले मैच के बाद खोज कमांड को कैसे रोकें?


131

क्या findपहला मैच खोजने के बाद कमांड को सही रोकने के लिए मजबूर करने का एक तरीका है ?


4
TheUseen: यह कारण कि यह पांच परिणामों के बाद आता है जब सिर से 5 तक पाइप किया जाता है क्योंकि पांच परिणामों के बाद सिर बाहर निकलता है। जब सिर बाहर निकलता है तो पाइप बंद हो जाता है और प्रोग्राम पाइपिंग को सिग्नल भेजता है और साथ ही समाप्त भी करता है। सीधे तौर पर आपको जवाब न देने के लिए क्षमा करें, जाहिर है आपको जवाब देने के लिए 50 प्रतिष्ठा की आवश्यकता है।
'17

जवाबों:


148

GNU या FreeBSD के साथ find, आप -quitविधेय का उपयोग कर सकते हैं :

find . ... -print -quit

NetBSD findसमतुल्य:

find . ... -print -exit

यदि आप सब करते हैं तो नाम छाप रहे हैं, और यह मानते हुए कि फ़ाइल नाम में नई रेखाएँ नहीं हैं, आप ऐसा कर सकते हैं:

find . ... -print | head -n 1

यह findपहले मैच के बाद नहीं रुकेगा , लेकिन संभवतः, दूसरे मैच के समय और बफ़रिंग के आधार पर या बाद में (बहुत)। मूल रूप से, findयह headपहले से ही चला गया है, जबकि पहले से ही चला गया है क्योंकि कुछ उत्पादन करने की कोशिश करता है, जब एक संकेत के साथ समाप्त किया जाएगा ।

ध्यान दें कि सभी शेल वापस आने के findबाद उस कमांड का इंतजार नहीं करेंगे head। बॉर्न शेल और एटी एंड टी के कार्यान्वयन ksh(जब गैर-इंटरएक्टिव) और yash(केवल अगर वह पाइपलाइन एक स्क्रिप्ट में अंतिम कमांड है) नहीं होगा, तो यह पृष्ठभूमि में चल रहा है। यदि आप किसी भी शेल में उस व्यवहार को देखेंगे, तो आप हमेशा उपरोक्त को बदल सकते हैं:

(find . ... -print &) | head -n 1

यदि आप मिली हुई फ़ाइलों के पथ को प्रिंट करने से अधिक कर रहे हैं, तो आप इस दृष्टिकोण की कोशिश कर सकते हैं:

find . ... -exec sh -c 'printf "%s\n" "$1"; kill "$PPID"' sh {} \;

( printfउस फ़ाइल के साथ जो कुछ भी आप कर रहे हैं उसे बदलें )।

findबाहर निकलने की स्थिति लौटने का साइड इफेक्ट है जो इस तथ्य को दर्शाता है कि यह हालांकि मारा गया था।

वास्तव में, बजाय SIGPIPE संकेत का उपयोग कर SIGTERM (के kill -s PIPEबजाय kill) (लेकिन अभी भी एक गैर शून्य से बाहर निकलें स्थिति वापसी होगी) के कारण कुछ गोले कि मौत के बारे में अधिक चुप रहने की जाएगी।


3
मामले में किसी को भी यह जांचने की आवश्यकता है कि क्या कोई फ़ाइल विधेय से मेल खाती है, जैसे ही एक पाया जाता है, बैश और जीएनयू में खोजें आप कर सकते हैं: if [[ $(find ... -print -quit) ]]; then ...यह सिर्फ परीक्षण करता है कि क्या कुछ भी मुद्रित मिला।
टोबिया

$(…)यदि आप केवल एकल कोष्ठक ( [ … ]) का उपयोग कर रहे हैं, तो कोटेशन में भाग डालने के लिए @ टोबिया बेहतर है ।
phk

@ एफके सिवाय मैं एकल ब्रैकेट का उपयोग नहीं कर रहा हूं (क्योंकि वे भयानक हैं) इसलिए मुझे उद्धरण का उपयोग करने की आवश्यकता नहीं है।
तोबिया

2
@ टोबिया, [एक मानक कमांड है। यह इतना अधिक नहीं है कि कमान भयानक है, लेकिन जिस तरह से बॉर्न-जैसे गोले कमांड लाइन को पार करते हैं। [[...]]एक ksh निर्माण है जिसके विभिन्न गोले स्वयं के मुद्दे हैं। उदाहरण के लिए, हाल ही में जब तक आप (आप की जरूरत है ) [[ $(...) ]]में काम नहीं करेगा । को छोड़कर , आपको उद्धरणों की आवश्यकता है , कार्यान्वयन के बीच असंगत अंतर है और यहां तक ​​कि कुछ में बग और कई बग के लिए संस्करण भी हैं। व्यक्तिगत रूप से, मुझे पसंद है । zsh[[ -n $(...) ]]zsh[[ $a = $b ]][[ =~ ]][
स्टीफन चेज़लस

क्या है ...? ।
kyb

11
find . -name something -print -quit

यह प्रिंट करने के बाद पहले मैच के बाद टर्मिनेशन पाते हैं।

मैचों और प्रिंट परिणामों की एक विशिष्ट राशि के बाद समाप्त खोजें:

find . -name something -print | head -n 5

आश्चर्यजनक रूप से पर्याप्त - सिर अब 5 मैचों के बाद स्ट्रिंग को समाप्त कर देता है, हालांकि मुझे नहीं पता कि कैसे या क्यों।

यह परीक्षण करना बहुत आसान है। बस खोज को एक रूट पर खोजें , जिसके परिणामस्वरूप हजारों हो सकते हैं, शायद कम से कम एक मिनट या अधिक समय लेते हुए और भी मैच। लेकिन जब "हेड" "पाई" में पाइप किया जाता है, तो सिर में परिभाषित लाइनों की निर्दिष्ट मात्रा के बाद समाप्त हो जाएगा (डिफ़ॉल्ट सिर 10 दिखाता है, लाइनों को निर्दिष्ट करने के लिए "हेड-एन" का उपयोग करें)।

ध्यान दें कि यह "हेड-एन" निर्दिष्ट न्यूलाइन वर्ण गणना तक पहुंचने के बाद समाप्त हो जाएगा और इसलिए किसी भी मैच में मल्टीपल न्यूलाइन वर्ण होंगे जो तदनुसार गणना करेंगे।


मैंने यह भी देखा है कि 'आउटपुट के साथ हेड' होने के बाद यह प्रोग्राम समाप्त हो जाता है, लेकिन लगातार गोले में नहीं। मुझे लगता है कि यह अपने सवाल का गुण है - सौभाग्य से बश के लिए जवाब पहले से ही स्टैकऑवरफ्लो के बैश पर है: बैश स्क्रिप्ट के साथ हेड एंड टेल व्यवहार । यह निष्कर्ष निकालने के लिए मेरे लिए पर्याप्त जानकारी है कि क्या कार्यक्रम समाप्त होता है या पृष्ठभूमि में निष्पादित करना जारी रहता है या नहीं, यह SIGPIPE की प्रतिक्रिया पर निर्भर करता है - हत्या डिफ़ॉल्ट है।
ऋषि

मेरा मतलब था 'कार्यक्रमों * / गोले' के पार, लेकिन जाहिरा तौर पर unix.stackexchange.com यह पसंद करेगा कि मैं इसे अपनी पहली टिप्पणी को संपादित करने के बजाय एक दूसरी टिप्पणी के रूप में लॉग इन करूं (यह एक स्टैकएक्सचेंज, साइट-विशिष्ट नीति निर्णय है)। इसके अलावा, अब मैं देखता हूं कि @Ruste ने शीर्ष पर इस आशय की टिप्पणी की, जिससे मुझे शुरू में मदद नहीं मिली क्योंकि मैं सीधे उत्तर देने के लिए गया ...
ऋषि

2

मनोरंजन के प्रयोजनों के लिए, यहाँ एक आलसी बैश में जनरेटर है। यह उदाहरण वर्तमान निर्देशिका में फ़ाइलों पर एक रिंग उत्पन्न करता है। फिर भी आप चाहते हैं कि कई पढ़ें kill %+(शायद सिर्फ 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

अगर झंडा के साथ इस्तेमाल किया जाता है -m, तो grep भी लौटता है

find stuff | grep -m1 .

यह पहली पंक्ति को खोजने के बाद छपेगी।

इस के बीच का अंतर यह find stuff -print -quit | head -1है कि यदि खोज काफी तेज है, तो जीआरईपी समय में प्रक्रिया को रोकने में सक्षम नहीं हो सकता है (हालांकि वास्तव में कोई फर्क नहीं पड़ता), जबकि अगर खोज लंबी है तो यह बहुत जरूरी नहीं है को खोजने के लिए प्रिंट करेगा लाइनों।

इसके बजाय यह काम करता है बिजीबॉक्स फाइंड के साथ, हालांकि बिजीबॉक्स ग्रीप के पास भी इसकी -mवास्तव में जरूरत नहीं है

find /tmp/stuff -exec "sh" "-c" "eval 'echo {}; { kill \$PPID; }'" \;

यह खोज प्रक्रिया के बारे में एक संदेश थूक देगा (आमतौर पर) सिग्‍टरम सिग्‍नल को प्राप्‍त होता है, लेकिन यह आउटपुट रनिंग शेल का है, न कि खोज कमांड का, ताकि यह कमांड आउटपुट के साथ गड़बड़ न करे, अर्थ पाइप या रीडायरेक्‍ट सिर्फ लाइन आउटपुट करेगा मिल कर खोजा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.