यदि कोई -एक्सईक विफल रहता है, तो उसे तोड़ दें


14

क्या ऐसा लिखने का कोई तरीका है findताकि यह टूट जाए अगर कोई -execएक फ़ाइल पर कार्रवाई विफल हो जाती है?

ईजी ( javacआसानी से एक प्रोग्राम के रूप में उपयोग किया जाता है जो कुछ फाइलों पर और किसी अन्य कारण से 1 का एग्जिट कोड वापस कर सकता है):

$ echo "public classXX A{}" >> A.java
$ echo "public class B{}" >> B.java
$ find . -iname \*.java -exec javac {} \;
./A.java:1: error: class, interface, or enum expected
public classXX A{}
       ^
1 error

ऊपर दिए गए उदाहरण में, हालाँकि execफ़ाइल A.javaविफल रही (और 1 का निकास कोड लौटाया गया), findकमांड आगे बढ़ी और B.javaसाथ ही फ़ाइल संकलित की गई। वहाँ से बाहर तोड़ने का एक तरीका है findया मैं forइसके बजाय किसी न किसी रूप का उपयोग करना चाहिए ?

मेरे खोज का संस्करण:

$ find -version  | head -1
find (GNU findutils) 4.4.2

जवाबों:


5

मुझे लगता है...

find ... -exec sh -c 'cmd "$0" || kill $PPID' \{\} \;

... बस के बारे में किसी भी के लिए चाल करना चाहिए find


धन्यवाद @ गिले। क्या करता $0है?
माइकस

1
$0पहला तर्क है sh -c( $1दूसरा वाला है, आदि) - परंपरागत रूप से निष्पादित किए जा रहे कार्यक्रम का नाम है, लेकिन यहां आप एक स्निपेट निष्पादित कर रहे हैं, और फ़ाइल नाम को संसाधित किया जा रहा है $0जो कुछ समझ में आता है (जैसे आप आसानी से देखते हैं इसमें ps)। वहाँ एक विचार का स्कूल है (जो मैं स्पष्ट रूप से संबंधित नहीं हूं) जिसमें कहा गया है कि $0हमेशा निष्पादन योग्य होना चाहिए और आपको sh -c 'cmd "$1" …' sh {}कुछ ऐसा लिखना चाहिए ।
गिल्स एसओ- बुराई को रोकें '

@ गिल्स - बहुत चालाक। बहुत बहुत धन्यवाद। मैंने इसे पूर्वस्कूली के रास्ते में कार में निकाला, लेकिन मुझे इसके बारे में कई मिनट तक सोचना पड़ा। यह स्मार्ट है - मैं इसका उपयोग करने वाला हूं। मेरे लिए वास्तव में इस पर क्लिक किया गया एक संपादन था जिसे मैंने स्टीफन के अपने स्वयं के एक पोस्ट पर पढ़ने को याद किया जिसमें उन्होंने find-sh $0एक findबयान के अंत में जोड़ा । यह मेरी राय में अधिक उपयोगी लगता है, हालांकि मुझे लगता है कि यह लंबे समय के बाद है जो सबसे अधिक मायने रखता है।
माइकस

यह ऊपर के मामले के लिए काम नहीं कर रहा है। find . -iname \*.java -exec sh -c 'javac "${0}" || kill '$$ {} \;फ़ाइल A.javaविफल होने के बाद और, अभी भी, फ़ाइल B.java संकलित हो जाती है।
मार्कस जूनियस ब्रूटस

@MarcusJuniusBrutus - मैंने इसे ठीक किया। मुझे आपकी टिप्पणी पहले देखनी चाहिए थी। फिर से क्षमा।
माइकस

4

कम से कम GNU के साथ findआप उपयोग कर सकते हैं:

find ... -exec ... -o -quit

मुझे यह स्पष्ट करने में परेशानी हो रही है कि निष्पादन कहाँ रुकता है और -o शुरू होता है। दोनों find . -iname \*.java -exec javac {} -o -quit \;और find . -iname \*.java -exec javac {} \; -o -quit \;असफल (अलग-अलग तरीकों से)
मार्कस जुनियस ब्रूटस

@MarcusJuniusBrutus ( \;और इस मामले में -execपहले -o -quit) की जरूरत है, लेकिन कहीं और नहीं हो सकता है।
हौके लैजिंग

2
उपयोग करना -exec ... -o -quitमेरे लिए काम नहीं करता है। यह किसी भी फाइल को प्रोसेस नहीं करता है । हालांकि इस लाइन काम करता है: find . -iname \*.java -not -exec javac '{}' \; -quit: -quitअगर कहा जाता है -execगलत है, यानी। गैर-शून्य के साथ रिटर्न।
सवंतो

find . -iname \*.java -exec javac {} \; -o -quit, किसी भी फाइल को प्रोसेस करने में विफल रहता है। अजीब तरह से, फाइलों find . -iname \* -exec echo 'foo' \; -o -quit को "प्रोसेस" करता है।
मार्कस जूनियस ब्रूटस

0

अपने findमैनुअल से परामर्श करें । @ Hauke ​​के जवाब ने मुझे देखने के लिए प्रेरित किया और QNX के खोज में एक -abortविकल्प है जो GNU -quitविकल्प के समान लगता है। यह मेरे लिए काम करता है बशर्ते कि मैं उपयोग करूँ \(और \)समूह भावों के लिए:

find . -mtime -4 -name <pattern> \( -exec my_cmd {} \; -o  -abort \) 

नोट: Parens के बिना, यह पहली फ़ाइल को निरस्त करता है।

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