bash 使用 xargs 将 stdin 分配给变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3450960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using xargs to assign stdin to a variable
提问by User1
All that I really want to do is make sure everything in a pipeline succeeded and assign the last stdin to a variable. Consider the following dumbed down scenario:
我真正想做的就是确保管道中的一切都成功并将最后一个标准输入分配给一个变量。考虑以下简化的场景:
x=`exit 1|cat`
x=`exit 1|cat`
When I run declare -a, I see this:
当我运行时declare -a,我看到:
declare -a PIPESTATUS='([0]="0")'
declare -a PIPESTATUS='([0]="0")'
I need some way to notice the exit 1, so I converted it to this:
我需要某种方式来注意exit 1,所以我将其转换为:
exit 1|cat|xargs -I {} x={}
exit 1|cat|xargs -I {} x={}
And declare -agave me:
并declare -a给了我:
declare -a PIPESTATUS='([0]="1" [1]="0" [2]="0")'
declare -a PIPESTATUS='([0]="1" [1]="0" [2]="0")'
That is what I wanted, so I tried to see what would happen if the exit 1didn't happen:
这就是我想要的,所以我试着看看如果exit 1没有发生会发生什么:
echo 1|cat|xargs -I {} x={}
echo 1|cat|xargs -I {} x={}
But it fails with:
但它失败了:
xargs: x={}: No such file or directory
xargs: x={}: No such file or directory
Is there any way to have xargs assign {}to x? What about other methods of having PIPESTATUSwork and assigning the stdin to a variable?
有没有办法让 xargs 分配{}给x?其他PIPESTATUS工作和将标准输入分配给变量的方法呢?
Note: these examples are dumbed down. I'm not really doing an exit 1, echo 1or a cat, but used these commands to simplify so we can focus on my particular issue.
注意:这些示例被简化了。我真的不这样做的exit 1,echo 1或者cat,但使用这些命令简化,所以我们可以专注于我的具体问题。
回答by Douglas Leeder
xargsis run in a child process, as are all the commands you call. So they can't effect the environment of your shell.
xargs在子进程中运行,您调用的所有命令也是如此。所以它们不能影响你的 shell 的环境。
You might be able to do something with named pipes (mkfifo), or possible bash's readfunction?
您也许可以使用命名管道 ( mkfifo) 或可能的 bashread函数来执行某些操作?
EDIT:
编辑:
Maybe just redirect the output to a file, then you can use PIPESTATUS:
也许只是将输出重定向到一个文件,然后您可以使用 PIPESTATUS:
command1 | command2 | command3 >/tmp/tmpfile
## Examine PIPESTATUS
X=$(cat /tmp/tmpfile)
回答by Paused until further notice.
When you use backticks (or the preferred $()) you're running those commands in a subshell. The PIPESTATUSyou're getting is for the assignment rather than the piped commands in the subshell.
当您使用反引号(或首选$())时,您是在子 shell 中运行这些命令。在PIPESTATUS你得到是分配,而不是子shell的管道命令。
When you use xargs, it knows nothing about the shell so it can't make variable assignments.
当您使用 时xargs,它对外壳一无所知,因此无法进行变量分配。
Try set -o pipefailthen you can get the status from $?.
尝试set -o pipefail然后您可以从$?.
回答by timo
How about ...
怎么样 ...
read x <<<"$(echo 1)"
read x < <(echo 1)
echo "$x"
回答by timo
Why not just populate a new array?
为什么不填充一个新数组?
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]}"
回答by will
There are already a few helpful solutions. It turns out that I actually had an example that matches the question as framed above; close-enough anyway.
已经有一些有用的解决方案。事实证明,我实际上有一个与上述问题相匹配的示例;反正足够接近。
Consider this:
考虑一下:
XX=$(ls -l *.cpp | wc -l | xargs -I{} echo {})
echo $XX
3
Meaning that I had 3 x .cppfiles to in my working directory. Now $XXis 3 and I can make use of that result in my script. It is contrived, because I don't actually need the xargsin this example. It works though.
这意味着.cpp我的工作目录中有 3 个 x文件。现在$XX是 3,我可以在我的脚本中使用该结果。这是人为的,因为xargs在这个例子中我实际上并不需要。它虽然有效。
In the example from the question ...
在问题的例子中......
x=`exit 1|cat`
I don't think that will give you what was specified. exitwill quit the sub-shell before the catgets a mention. Also on that note,
我认为这不会给你指定的内容。 exit将在cat提及之前退出子外壳。也在那个笔记上,
I might start with something like
我可能会从类似的东西开始
declare -a PIPESTATUS='([0]="0")'
x=$?
xnow has the status from the last command.
x现在具有上一个命令的状态。
回答by TRicks43
Assign each line of input to an array, e.g. all python files in a directory
将每一行输入分配给一个数组,例如目录中的所有python文件
declare -a pyFiles=($(ls -l *.py | awk '{print }'))
where $9 is the nineth field in ls -l corresponding to the filename
其中 $9 是 ls -l 中对应于文件名的第九个字段

