लूप आउटपुट के लिए पाइपिंग स्थानीय चर संशोधन को रोकता है


11

मैं एक साधारण बैश फ़ंक्शन लिखने की कोशिश कर रहा हूं, जो इसके तर्कों, कई फाइलों और / या निर्देशिकाओं के रूप में लेता है। यह होना चाहिए:

  1. पूरी तरह से फ़ाइल नाम योग्य।
  2. उन्हें क्रमबद्ध करें।
  3. डुप्लिकेट निकालें।
  4. वास्तव में मौजूद सभी को प्रिंट करें।
  5. गैर-मौजूद फ़ाइलों की संख्या लौटाएँ।

मेरे पास एक स्क्रिप्ट है जो लगभग वही करता है जो मैं चाहता हूं, लेकिन छंटनी पर गिर जाता है। स्क्रिप्ट का वापसी मूल्य सही होने के साथ ही सही है, लेकिन आउटपुट (अनसोल्ड और डुप्लिकेट) नहीं है। यदि मैं | sort -uबयान को संकेत के रूप में बता देता हूं , तो आउटपुट सही है लेकिन रिटर्न वैल्यू हमेशा है 0

समस्या को हल करने के लिए एनबी सिंपल समाधान स्वागत योग्य हैं लेकिन सवाल वास्तव में यह है कि मेरे पास कोड में ऐसा क्यों होता है। यही है, क्यों पाइप को जोड़ने से स्क्रिप्ट में वृद्धि को रोकने के लिए प्रतीत होता है r?

यहाँ स्क्रिप्ट है:

function uniqfile
{
    local r=0 

    for arg in "$@"
    do  
        readlink -e "$arg" || (( ++r ))

    done #| sort -u    ## remove that comment

    return $r
}

बस एक छोटा सा अवलोकन। आप कम कर सकते हैं for arg in "$@"करने के लिए for arg। "अगर मैं काम करता हूं ...?" मौजूद नहीं है, फिर "" $ @ "" मान लिया गया है। " - मदद के लिए
मैनटवर्क

जवाबों:


15

यह एक प्रसिद्ध बैश पिटफॉल है, इस विशेषता के कारण :

एक पाइप लाइन में प्रत्येक कमांड को एक अलग प्रक्रिया के रूप में निष्पादित किया जाता है (यानी, एक सबशेल में)।

ताकि संशोधित चर उप-भाग में स्थानीय हों, और माता-पिता में एक बार दिखाई न दें।

इससे बचने के लिए, प्रक्रिया प्रतिस्थापन के साथ, पाइपलाइन से बचने के लिए अपने कोड को फिर से जमा करें:

 for arg in "$@"
    do  
        readlink -e "$arg" || (( ++r ))

    done > >(sort -u)

धन्यवाद। एक दम बढ़िया। मुझे आश्चर्य है कि अगर आप मुझे >(..command..)निर्माण का नाम बता सकते हैं । मुझे लगता है कि मुझे पता है कि यह कैसे काम करता है लेकिन मुझे लगता है कि मुझे कुछ और पढ़ना चाहिए।
tjm

2
@tjm: इसे प्रक्रिया प्रतिस्थापन
enzotib

बाश में प्रक्रिया प्रतिस्थापन के कई रूप हैं: tldp.org/LDP/abs/html/process-sub.html
slm

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

3

| sort -uबलों पूर्ववर्ती बिट (ताकि पाश के लिए पूरे) एक उप प्रक्रिया में चलाने के लिए (बैश में पुनर्निर्देशित करने के लिए एक 'STDOUT' की जरूरत है sort'STDIN'। (इंटरनेट सोचने के लिए लगता है kshऔर bashसंभाल इस मामले थोड़ा अलग ढंग से .. पहले या अंतिम पाइप अनुक्रम में कमांड एक उपखंड में डाल दिया जाता है? "

यह धागा एक ऐसी ही समस्या से गुजरता है, और इसके अंत में एक साफ समाधान है: http://ubuntuforums.org/showthread.php?t=312017

अंश
    #!/bin/bash
    exec 3< <(du | sort -n)  

    n=0
    while read size dir; do
      [ $size -gt 1000 ] && ((n++))
    done <&3
    exec 3<&-

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