2017-11-12 17 views
6

के माध्यम से कॉल या अलग है, नीचे देखें:बैश "WC -l" आदेश उत्पादन जब मैं दो बराबर आदेशों बैश में मैं ("WC -l" आदेश से) विभिन्न उत्पादन मिला जारी करता है, तो टी

[email protected]:~# ls /usr/bin -lha | tee >(wc -l) >(head) > /dev/null 
total 76M 
drwxr-xr-x 2 root root  20K Nov 11 18:58 . 
drwxr-xr-x 10 root root  4.0K Oct 8 15:31 .. 
-rwxr-xr-x 1 root root  51K Feb 22 2017 [ 
-rwxr-xr-x 1 root root  96 Jan 19 2017 2to3-3.5 
-rwxr-xr-x 1 root root  23K Mar 22 2017 addpart 
lrwxrwxrwx 1 root root  26 May 10 2017 addr2line -> x86_64-linux-gnu- addr2line 
lrwxrwxrwx 1 root root  6 Dec 13 2016 apropos -> whatis 
-rwxr-xr-x 1 root root  15K Sep 13 19:47 apt 
-rwxr-xr-x 1 root root  79K Sep 13 19:47 apt-cache 
137 
[email protected]:~# ls /usr/bin -lha | wc -l 
648 

क्या क्या मैं याद कर रहा हूँ

यह अजीब बात है, लेकिन जब मैं इसे इस तरह कहते हैं तो यह और भी अजनबी उत्पादन हो जाता है:

[email protected]:~# ls /usr/bin -lha | tee >(wc) >(wc) > /dev/null 
648 6121 39179 
648 6121 39179 
[email protected]:~# ls /usr/bin -lha | tee >(wc) >(wc) > /dev/null 
648 6121 39179 
648 6121 39179 
[email protected]:~# ls /usr/bin -lha | tee >(wc) >(wc -l) > /dev/null 
648 
[email protected]:~#  648 6121 39179 

एसिंक्रोनस रूप से चल रहा है आदेशों की तरह लगता है और अलग-अलग समय में समाप्त होता है ... या यह क्या हो सकता है?

+1

हां, प्रक्रिया प्रतिस्थापन असीमित रूप से चलाया जाता है, [मैन्युअल] देखें [https://www.gnu.org/software/ बैश/मैनुअल/html_node/प्रक्रिया Substitution.html)। –

+0

ठीक है, लेकिन इसे कैसे ठीक करें, वास्तविक आउटपुट समाप्त होने तक प्रोग्राम को कैसे प्रतीक्षा करें? या यहां कोई समाधान नहीं है? –

+0

आप वास्तव में क्या हासिल करना चाहते हैं? 'एलएस के आउटपुट दोनों प्राप्त करें सिर 'और 'एलएस | wc -l'? –

उत्तर

7

सरल जवाब:

ठीक करने का तरीका:

ls /usr/bin -lha | tee --output-error=exit-nopipe >(wc -l) >(head) > /dev/null 

विवरण:

आदेश head केवल, इनपुट के सिर प्रिंट तो यह जब तक यह पर्याप्त हो जाता है अपना काम समाप्त कर सकते हैं इनपुट, फिर सभी इनपुट के इंतजार किए बिना बाहर निकलता है।

तो चलिए को सरल "head" के साथ कमांड को प्रतिस्थापित करें।

ls /usr/bin -lha | tee >(wc -l) >(read l; echo $l) > /dev/null

सरल "head" केवल एक लाइन, फिर बाहर निकलें, जो कि पाइप फ़ाइल tee खत्म इसे करने के लिए सभी डेटा स्थानांतरित करने से पहले तुरंत बंद कर दिया जाता है का कारण बनता है पढ़ा जाएगा।

तो इसमें कोई संदेह नहीं है, आपको सरल "head" के साथ एक ही परिणाम मिल जाएगा। wc अभी भी गलत नंबर प्रिंट करता है।

आपकी समस्या की जड़ हो, मुझे लगता है कि आप अपने आप को निष्कर्ष निकाल सकते हैं, कि tee के उत्पादन में फ़ाइलों में से एक जल्दी बंद कर दिया है, tee एक लेखन त्रुटि मारता है, और फिर अन्य आउटपुट फाइलों को लिखित रूप से बंद हो जाता है।

मूल कारण समझने के बाद, मुझे लगता है कि मैन पेज में निम्नलिखित अनुभाग को समझना आपके लिए बहुत आसान होगा।

MODE determines behavior with write errors on the outputs: 
    'warn' diagnose errors writing to any output 

    'warn-nopipe' 
      diagnose errors writing to any output not a pipe 

    'exit' exit on error writing to any output 

    'exit-nopipe' 
      exit on error writing to any output not a pipe 

    The default MODE for the -p option is 'warn-nopipe'. The default operation 
    when --output-error is not specified, is to exit immediately on error writing to 
    a pipe, and diagnose errors writing to non pipe outputs. 

कुछ अतिरिक्त शब्द

असल में अगर आप अपने समस्याग्रस्त कमांड लाइन में एक नियमित रूप से फ़ाइल के साथ <(wc -l) की जगह, तो आप पाएंगे फ़ाइल आकार हमेशा 16384 या 20480 है, जो 4096.

के सभी गुणकों हैं हो जाएगा

4096 अधिकांश यूनिक्स सिस्टम के लिए PIPE_BUF का मान है। यदि आप जानते हैं कि PIPE_BUF है, तो आप आसानी से समझेंगे कि फाइल का आकार हमेशा 4096 का क्यों होता है।

+0

कमांड का स्पष्टीकरण [यहां] (https://explainshell.com/explain?cmd=ls+%2Fusr%2Fbin+-lha+%7C+tee+--output-error%3Dexit-nopipe+%3E%28wc+-l%29+ % 3E% 28head% 29 +% 3E +% 2Fdev% 2Fnull) –

संबंधित मुद्दे