簡體   English   中英

bash“wc -l”命令輸出在呼叫或通過tee時有所不同

[英]bash “wc -l” command output differs if call or through tee

當我在Bash中發出兩個等效命令時,我得到了不同的輸出(來自“wc -l”命令),見下文:

root@devel:~# 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
root@devel:~# ls /usr/bin -lha | wc -l
648

我錯過了什么?

這很奇怪,但是當我以這種方式調用它時,它會輸出更奇怪的輸出:

root@devel:~# ls /usr/bin -lha | tee >(wc) >(wc) > /dev/null
648    6121   39179
648    6121   39179
root@devel:~# ls /usr/bin -lha | tee >(wc) >(wc) > /dev/null
648    6121   39179
648    6121   39179
root@devel:~# ls /usr/bin -lha | tee >(wc) >(wc -l) > /dev/null
648
root@devel:~#     648    6121   39179

看起來像異步運行的命令,並在不同的時間結束......或者它可以是什么?

簡單回答:

怎么修:

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

細節:

命令head只打印輸入的頭部,因此只要輸入足夠就可以完成其工作,然后退出而不等待所有輸入。

所以讓我們用簡單的"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或32768或36864或28672或......,所有這些都是4096.(對常規文件的寫入不完整,因為tee早先中止。如果寫入完成,文件大小將是任何值。)

對於大多數類UNIX系統,4096是PIPE_BUF的值。 如果您知道PIPE_BUF是什么,您將很容易理解為什么文件大小始終是4096的倍數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM