使用xargs将stdin分配给变量

时间:2010-08-10 16:02:27

标签: bash pipe xargs

我真正想做的就是确保管道中的所有内容都成功并将最后一个stdin分配给变量。考虑以下愚蠢的情景:

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工作并将stdin分配给变量的其他方法呢?

注意:这些例子都是愚蠢的。我实际上并不是exit 1echo 1cat,而是使用这些命令进行简化,以便我们专注于我的特定问题。

6 个答案:

答案 0 :(得分:3)

xargs在子进程中运行,就像您调用的所有命令一样。所以它们不会影响shell的环境。

您可以使用命名管道(mkfifo)或可能的bash read函数执行某些操作吗?

编辑:

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

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

答案 1 :(得分:3)

使用反引号(或首选的$())时,您将在子shell中运行这些命令。你获得的PIPESTATUS是用于赋值而不是子shell中的管道命令。

使用xargs时,它对shell一无所知,因此无法进行变量赋值。

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

答案 2 :(得分:0)

怎么样......

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

echo "$x"

答案 3 :(得分:0)

为什么不填充一个新阵列?

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]}"

答案 4 :(得分:0)

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

考虑一下:

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

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

在问题示例中...

x=`exit 1|cat`

我认为这不会给您指定的内容。 exit将在cat被提及之前退出子外壳。此外,

我可能会以类似的方式开始

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

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

答案 5 :(得分:0)

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

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

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