【问题标题】:Using xargs to assign stdin to a variable使用 xargs 将标准输入分配给变量
【发布时间】:2011-03-27 22:18:24
【问题描述】:

我真正想做的就是确保管道中的所有内容都成功,并将最后一个标准输入分配给一个变量。考虑以下简化的场景:

x=`exit 1|cat`

当我运行declare -a 时,我看到了这个:

declare -a PIPESTATUS='([0]="0")'

我需要一些方法来注意exit 1,所以我将其转换为:

exit 1|cat|xargs -I {} x={}

declare -a 给了我:

declare -a PIPESTATUS='([0]="1" [1]="0" [2]="0")'

这就是我想要的,所以我试着看看如果exit 1 没有发生会发生什么:

echo 1|cat|xargs -I {} x={}

但它失败了:

xargs: x={}: No such file or directory

有没有办法让 xargs 将 {} 分配给 x?让PIPESTATUS 工作并将标准输入分配给变量的其他方法呢?

注意:这些示例被简化了。我并没有真正使用exit 1echo 1cat,而是使用这些命令进行简化,以便我们可以专注于我的特定问题。

【问题讨论】:

    标签: bash pipe xargs


    【解决方案1】:

    当您使用反引号(或首选的$())时,您是在子shell 中运行这些命令。您得到的 PIPESTATUS 用于分配,而不是子外壳中的管道命令。

    当你使用xargs时,它对shell一无所知,所以它不能进行变量赋值。

    尝试set -o pipefail,然后您可以从$?获取状态。

    【讨论】:

    • pipefail 是一个不错的选择。但是,我希望我能获得管道中所有内容的 PIPESTATUS。
    【解决方案2】:

    xargs 在子进程中运行,您调用的所有命令也是如此。所以它们不会影响你的 shell 环境。

    您也许可以使用命名管道 (mkfifo) 或可能的 bash 的 read 函数来做一些事情?

    编辑:

    也许只是将输出重定向到一个文件,然后你可以使用 PIPESTATUS:

    command1 | command2 | command3 >/tmp/tmpfile
    ## Examine PIPESTATUS
    X=$(cat /tmp/tmpfile)
    

    【讨论】:

    • 我在想 read 可以做这样的事情。 echo 1|read x 没有用。你有例子吗?
    【解决方案3】:

    怎么样...

    read x <<<"$(echo 1)"
    read x < <(echo 1)
    
    echo "$x"
    

    【讨论】:

    • 有趣的想法。使用 (exit 1|cat) 仍然无法正确填充 PIPESTATUS。
    【解决方案4】:

    为什么不直接填充一个新数组?

    IFS=$'\n' read -r -d '' -a result < <(echo a | cat | cat; echo "PIPESTATUS='${PIPESTATUS[*]}'" )
    IFS=$'\n' read -r -d '' -a result < <(echo a | exit 1 | cat; echo "PIPESTATUS='${PIPESTATUS[*]}'" )
    
    echo "${#result[@]}"
    echo "${result[@]}"
    echo "${result[0]}"
    echo "${result[1]}"
    

    【讨论】:

      【解决方案5】:

      已经有一些有用的解决方案。事实证明,我实际上有一个与上述问题相匹配的示例;足够接近无论如何

      考虑一下:

       XX=$(ls -l *.cpp | wc -l  | xargs -I{} echo {})
       echo $XX
       3
      

      意味着我的工作目录中有 3 x .cpp 文件。现在$XX 是 3,我可以在我的脚本中使用该结果。这是人为的,因为在这个例子中我实际上并不需要xargs。但它确实有效。

      在问题的例子中......

      x=`exit 1|cat`
      

      我认为这不会给您指定的内容。 exit 将在 cat 被提及之前退出子 shell。同样在那个注释上,

      我可能会从类似的东西开始

      declare -a PIPESTATUS='([0]="0")'
      x=$?
      

      x 现在具有上一个命令的状态。

      【讨论】:

        【解决方案6】:

        将每一行输入分配给一个数组,例如目录中的所有python文件

        declare -a pyFiles=($(ls -l *.py | awk '{print $9}')) 
        

        其中 $9 是 ls -l 中与文件名对应的第九个字段

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-07
          • 1970-01-01
          • 1970-01-01
          • 2017-12-30
          • 1970-01-01
          相关资源
          最近更新 更多