एक -exec
कमांड को एक के साथ समाप्त किया जाना चाहिए ;
(ताकि आपको आमतौर पर टाइप करने \;
या ';'
शेल द्वारा व्याख्या से बचने की आवश्यकता हो ) या ए +
। अंतर यह है कि ;
, कमांड को एक बार प्रति फ़ाइल के साथ +
कहा जाता है, इसके साथ , इसे केवल कुछ समय के लिए संभव के रूप में कहा जाता है (आमतौर पर एक बार, लेकिन कमांड लाइन के लिए अधिकतम लंबाई होती है, इसलिए इसे सभी फ़ाइल नाम के साथ विभाजित किया जा सकता है) । इस उदाहरण को देखें:
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
आपकी कमांड में दो त्रुटियां हैं:
सबसे पहले, आप उपयोग करते हैं {};
, लेकिन ;
स्वयं का एक पैरामीटर होना चाहिए।
दूसरा, कमांड का अंत होता है &&
। आपने निर्दिष्ट "रन खोजें, और यदि वह सफल था, तो नाम वाली फ़ाइल को हटा दें {};
।" यदि आप -exec
कमांड में शेल सामान का उपयोग करना चाहते हैं , तो आपको इसे शेल में स्पष्ट रूप से चलाने की आवश्यकता है, जैसे -exec sh -c 'ffmpeg ... && rm'
।
हालाँकि आपको बैश कमांड के अंदर {} को नहीं जोड़ना चाहिए, यह विशेष वर्ण होने पर समस्याएं पैदा करेगा। इसके बजाय, आप खोल के बाद अतिरिक्त पैरामीटर पास कर सकते हैं -c command_string
(देखें man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
आप देखते हैं कि $
पहले उदाहरण में शेल द्वारा चीज़ का मूल्यांकन किया गया है। कल्पना कीजिए कि $(rm -rf /)
:-) नामक एक फाइल थी
(साइड नोट: इसकी -
जरूरत नहीं है, लेकिन कमांड के बाद पहला वैरिएबल वेरिएबल को सौंपा गया है $0
, जो कि एक विशेष वेरिएबल है, जिसमें सामान्य रूप से प्रोग्राम का नाम रन और सेटिंग होता है, जो कि पैरामीटर के लिए थोड़ा अशुद्ध है, हालांकि यह जीता है 'शायद यहाँ कोई नुकसान नहीं पहुँचाता, इसलिए हम इसे सिर्फ -
और शुरू करने के लिए निर्धारित करते हैं $1
।'
तो आपकी आज्ञा कुछ इस तरह हो सकती है
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
लेकिन एक बेहतर तरीका है। समर्थन and
और पाते हैं or
, तो आप की तरह सामान कर सकते हैं find -name foo -or -name bar
। लेकिन यह भी साथ काम करता है -exec
, जो सही मूल्यांकन करता है यदि आदेश सफलतापूर्वक बाहर निकलता है, और यदि नहीं तो गलत है। इस उदाहरण को देखें:
$ ls
false true
$ find * -exec {} \; -and -print
true
यह केवल प्रिंट चलाता है यदि कमांड सफलतापूर्वक था, जो इसके लिए किया था, true
लेकिन इसके लिए नहीं false
।
तो आप एक के साथ जंजीर के दो निष्पादन विवरणों का उपयोग कर सकते हैं -and
, और यह केवल बाद वाले को निष्पादित करेगा यदि पूर्व सफलतापूर्वक चलाया गया था।