【问题标题】:Counting and recording the number of arguments passed in a pipe计算并记录管道中传递的参数数量
【发布时间】:2014-07-14 00:22:56
【问题描述】:

有没有办法计算和记录通过管道的参数数量?我正在从长度未知的文件中传输值。我可以使用 tee 将数字转储到 STDOUT,但不能将它们放入变量中:

seq 10 | tee >(wc -l) | xargs echo 

我感兴趣的是这对于美学和我自己的理解是否可行,而不是一些迂回的替代方案,例如重新扫描(非 txt)file_of_unknown 长度两次,或写入实际文件然后读回,等等。

谢谢!

【问题讨论】:

    标签: bash unix pipe tee


    【解决方案1】:

    管道中的组件(例如 OP 中的tee)在子shell 中执行。因此,它不能修改父 shell 的变量。这是关于子shell 和shell 变量的一般规则。每个 shell 都有自己的变量;当(子)shell 启动时,父 shell 的(部分)变量被复制到子 shell,但父 shell 中的变量与子 shell 中的变量之间没有链接。

    您可以使用管道在子外壳之间进行通信,但在管道中您已经在这样做了,因此很难协调另一层,尽管这并非不可能。不过,美学不是很好。

    所以基本上你最好的方法就是你明确放弃的那个,“写入一个实际的文件然后读回”。这既简单又可靠,而且速度非常快,尤其是当文件位于内存中的临时文件系统上时(请参阅tmpfs)。

    顺便说一句,xargs 通常会在空白处拆分输入行以生成参数,因此通常它接收的参数数量与它读取的行数不同。

    【讨论】:

      【解决方案2】:

      这是你要找的吗?

      sh$ seq 10 | tee >(wc -l > /tmp/f) | xargs echo; V=$(cat </tmp/f)
      1 2 3 4 5 6 7 8 9 10
      sh$ echo $V
      10
      

      如果您不喜欢使用临时文件(我应该使用 mktemp...),可以使用 fifo (mkfifo) 代替吗?


      如果可以使用 stderr 作为输出,您可以将示例重写为:

      sh$ V=$(seq 10 | tee >(xargs echo 1>&2) | wc -l)
      1 2 3 4 5 6 7 8 9 10
      sh$ echo $V
      10
      

      【讨论】:

        猜你喜欢
        • 2017-10-16
        • 2012-10-24
        • 2021-08-23
        • 1970-01-01
        • 2019-12-19
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多