代码之家  ›  专栏  ›  技术社区  ›  urusai_na

如果调用或通过tee,bash“wc-l”命令输出不同

  •  7
  • urusai_na  · 技术社区  · 8 年前

    当我在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
    

    看起来命令是异步运行的,在不同的时间结束。。。或者可能是什么?

    1 回复  |  直到 8 年前
        1
  •  8
  •   Bruce    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

    简单的 “头部” 将只读取一行,然后退出,这会导致管道文件在之前立即关闭 tee 完成向其传输所有数据。

    所以毫无疑问,你们会得到同样的结果 “头部” . wc 仍然打印错误的号码。

    我想你可以总结一下,你的问题的根本原因是 球座 提前关闭, 点击a 写入错误 ,然后停止写入其他输出文件。

    在理解了根本原因之后,我认为您很容易理解手册页中的以下部分。

    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的倍数。(写入常规文件不完整,因为 球座 提前中止。如果写入完成,文件大小将为任意值。)

    4096是 PIPE_BUF 对于大多数类UNIX系统。如果你知道的话 管道BUF 是的,您很容易理解为什么文件大小总是4096的倍数。

    推荐文章