समझना (1) s -exec विकल्प (घुंघराले ब्रेस और प्लस चिन्ह)


17

निम्न आदेश का उपयोग करके, क्या कोई यह बता सकता है कि वास्तव में घुंघराले ब्रेसिज़ ({}) और प्लस साइन (+) का उद्देश्य क्या है?

और यदि उन्हें कमांड से बाहर रखा गया तो कमांड अलग तरीके से कैसे काम करेगी?

find . -type d -exec chmod 775 {} +

जवाबों:


19

घुंघराले ब्रेसिज़ को findकमांड के परिणामों से बदल दिया जाएगा , और chmodउनमें से प्रत्येक पर चलाया जाएगा। +बनाता है findसंभव के रूप में कुछ आदेशों के रूप में चलाने के लिए प्रयास (हां, तो chmod 775 file1 file2 file3के रूप में करने का विरोध किया chmod 755 file1, chmod 755 file2, chmod 755 file3)। उनके बिना कमांड सिर्फ एक त्रुटि देता है। यह सभी में समझाया गया है man find:

-exec command ;

      निष्पादित आदेश ; सच है अगर 0 स्थिति वापस आ गई है। निम्नलिखित सभी तर्कों को findकमांड में तर्क दिए जाने तक लिया जाता है जब तक कि ' ;' ' ' युक्त तर्क का सामना नहीं किया जाता है। स्ट्रिंग ' {}' को वर्तमान फ़ाइल नाम से बदल दिया जाता है जिसे हर जगह संसाधित किया जाता है यह कमांड के तर्कों में होता है, न कि केवल उन तर्कों में जहां यह अकेला है, जैसा कि कुछ संस्करणों में है find। ...

-exec command {} +

      -execकार्रवाई का यह संस्करण चयनित फ़ाइलों पर निर्दिष्ट कमांड चलाता है, लेकिन अंत में प्रत्येक चयनित फ़ाइल नाम को जोड़कर कमांड लाइन का निर्माण किया जाता है; कमांड की कुल संख्या का मिलान की गई फ़ाइलों की संख्या से बहुत कम होगा। ...


12

टेर्डन के जवाब के अलावा,

  • "जाहिर है" -exec …या तो एक अर्धविराम ( ;) या एक प्लस चिह्न ( +) के साथ समाप्त किया जाना चाहिए । अर्धविराम शेल में एक विशेष चरित्र है (या, कम से कम, हर शेल जो मैंने कभी इस्तेमाल किया है), इसलिए, यदि इसे कमांड के हिस्से के रूप मेंfind उपयोग किया जाना है, तो इसे बच जाना चाहिए या उद्धृत किया जाना चाहिए ( \;,)";" , या ';')।
  • इसके साथ -exec … ;, {}स्ट्रिंग किसी भी स्थिति में शून्य या दो या अधिक सहित कमांड में किसी भी समय दिखाई दे सकती है ।  देखें इस कारण है कि आप क्या करना चाहते हैं इसका एक उदाहरण के लिए -execउपयोग किए बिना {}  दो या दो से अधिक दिखावे मुख्य रूप से उपयोगी होते हैं, क्योंकि, (कम से कम) के कुछ संस्करणों में find, {}स्वयं एक शब्द होने की आवश्यकता नहीं है; इसके आरंभ या अंत में अन्य वर्ण हो सकते हैं; जैसे,

    find . -type f -exec mv {} {}.bak ";"
    

    इसके साथ -exec … +, {}स्ट्रिंग को अंतिम तर्क के रूप में प्रकट होना चाहिए+ । जैसी आज्ञा

    find . -name "*.bak" -exec mv {} backup_folder +
    

    गूढ़ find: missing argument to ‘-exec’त्रुटि संदेश में परिणाम ।

    • इसके लिए एक वर्कअराउंड है जो कमांड cpऔर mvकमांड के लिए विशिष्ट है

      find . -name "*.bak" -exec mv -t backup_folder {} +
      

      या

      find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
      

    {}अपने आप में एक शब्द होना चाहिए; इसके आरंभ या अंत में अन्य वर्ण नहीं हो सकते। और, (कम से कम) के कुछ संस्करणों में find, आपके पास एक से अधिक नहीं हो सकते हैं {}

  • एक संन्यास नोट: आप कह सकते हैं

    खोजो। -name "* .sh" -type f -executable -exec {} वैकल्पिक args यहाँ ";"

    अपनी प्रत्येक स्क्रिप्ट को चलाने के लिए। परंतु

    खोजो। -name "* .sh" -type f -executable -exec {} +

    मापदंडों के रूप में अन्य सभी के नाम के साथ आपकी एक स्क्रिप्ट चलाता है । यह कहने के समान है

    ./*.sh
    

    एक शेल कमांड के रूप में, findयह गारंटी नहीं देता है कि यह अपने परिणामों को क्रमबद्ध करता है, इसलिए आप चलने की गारंटी नहीं देते हैं aaa.sh (आपकी वर्णानुक्रमिक पहली *.shफ़ाइल) जैसा कि आप चलने के साथ होंगे ./*.sh

  • इसका एक पहलू findशुरुआती लोगों के लिए पूरी तरह से स्पष्ट नहीं हो सकता है कि कमांड लाइन, प्रभावी रूप से, एक आर्कन भाषा में एक निष्पादन योग्य कथन है। उदाहरण के लिए,

    find . -name "*.sh" -type f -executable -print
    

    माध्यम

    for each file
        if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
        then
            if it is a plain file (i.e., not a directory)
            then
                if it is executable (i.e., the appropriate `---x--x--x` bit is set)
                then
                    print the file’s name
                end if
            end if
        end if
    end loop
    

    या केवल,

    for each file
        if the file’s name matches `*.sh`  AND  it is a plain file  AND  it is executable
        then
            print the file’s name
        end if
    end loop
    

    कुछ -खोजशब्द निष्पादन योग्य क्रिया और परीक्षण दोनों हैं। विशेष रूप से, यह सच है -exec … ;; उदाहरण के लिए,

    find . -type f -exec grep -q cat {} ";" -print
    

    में अनुवाद करता है

    प्रत्येक फ़ाइल के लिए
        अगर यह एक सादा फ़ाइल है (यानी, निर्देशिका नहीं)
        फिर
            grep -q cat फ़ाइल नाम निष्पादित करें
            यदि प्रक्रिया सफल होती है (यानी, स्थिति 0 से बाहर निकलती है)
            फिर
                फ़ाइल का नाम प्रिंट करें
            अगर अंत
        अगर अंत
    अंत लूप

    जो स्ट्रिंग " cat" युक्त सभी फाइलों के नाम प्रिंट करेगा । और, जबकि यह कुछ grepऐसा है जो स्वयं ( -lकम-केस के साथ L) विकल्प के द्वारा कर सकता है, इसका उपयोग उन findफाइलों को खोजने के लिए करना उपयोगी हो सकता है जिनमें एक निश्चित स्ट्रिंग होती है और एक निश्चित आकार होती है और एक निश्चित मालिक के पास होती है। और एक निश्चित समय सीमा में संशोधित किए गए,…।

    हालांकि, यह काम नहीं करता है -exec … +। चूंकि -exec … +एक से अधिक फ़ाइलों के लिए एक कमांड निष्पादित करता है, इसलिए यह for each file …लूप के अंदर एक तार्किक स्थिति के रूप में उपयोग करने के लिए समझ में नहीं आता है ।

  • ऊपर का फ्लिप पक्ष यह है कि findआम तौर पर 0 के बाहर निकलने की स्थिति के साथ बाहर निकलता है जब तक कि आप इसे अमान्य तर्क नहीं देते हैं या यह एक निर्देशिका से सामना करता है जिसे यह नहीं पढ़ सकता है। यहां तक ​​कि अगर आप जिस प्रोग्राम को निष्पादित करते हैं, वह विफल रहता है (एक गैर-शून्य निकास स्थिति के साथ बाहर निकलता है),  तो find0. के बाहर निकलने की स्थिति के साथ बाहर निकल जाएगा।  यदि आप विफल के साथ निष्पादित होने वाले प्रोग्राम को छोड़कर-exec … + (गैर-शून्य निकास स्थिति के साथ बाहर निकलता है), findबाहर निकल जाएगा एक गैर-शून्य निकास स्थिति के साथ।

सिस्टम के एक जोड़े पर वास्तव में find(1) क्या findकरता है और परीक्षण के एक लाख संस्करणों के अलावा , द ओपन ग्रुप बेस स्पेसिफिकेशन्स अंक 7, 2013 संस्करण ने कुछ जानकारी प्रदान की, जो findकरना चाहिए, और नहीं करना चाहिए।


3
सावधान रहें कि आपके उपयोग ... -exec mv {} {}.bak ...का उदाहरण सभी findकार्यान्वयनों के साथ अपेक्षित रूप से काम करने के लिए गुरुंटेड नहीं है। POSIX मानक राज्यों {}को हमेशा पहचाने जाने के लिए अकेला दिखाई देना चाहिए, अन्यथा व्यवहार अपरिवर्तित रखने के लिए या पाथनाम द्वारा उन्हें बदलने के लिए स्वतंत्र है। पूर्व मामले में, आपका पूरा कमांड अनिवार्य रूप से सभी फाइलों को हटा देगा, लेकिन अंतिम एक पाया ...
jlliagre
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.