使用 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 工作并将标准输入分配给变量的其他方法怎么样?
注意:这些例子是简化的。我并没有真正执行 exit 1
、echo 1
或 cat
,而是使用这些命令进行简化,以便我们可以专注于我的特定操作问题。
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`
When I run declare -a
, I see this:
declare -a PIPESTATUS='([0]="0")'
I need some way to notice the exit 1
, so I converted it to this:
exit 1|cat|xargs -I {} x={}
And declare -a
gave me:
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 1
didn't happen:
echo 1|cat|xargs -I {} x={}
But it fails with:
xargs: x={}: No such file or directory
Is there any way to have xargs assign {}
to x
? What about other methods of having PIPESTATUS
work and assigning the stdin to a variable?
Note: these examples are dumbed down. I'm not really doing an exit 1
, echo 1
or a cat
, but used these commands to simplify so we can focus on my particular issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
当您使用反引号(或首选的
$()
)时,您将在子 shell 中运行这些命令。您获得的 PIPESTATUS 是用于分配的,而不是子 shell 中的管道命令。当您使用 xargs 时,它对 shell 一无所知,因此无法进行变量分配。
尝试
set -o pipelinefail
然后您可以从$?
获取状态。When you use backticks (or the preferred
$()
) you're running those commands in a subshell. ThePIPESTATUS
you're getting is for the assignment rather than the piped commands in the subshell.When you use
xargs
, it knows nothing about the shell so it can't make variable assignments.Try
set -o pipefail
then you can get the status from$?
.xargs
与您调用的所有命令一样在子进程中运行。所以它们不会影响你的 shell 的环境。您也许可以使用命名管道 (
mkfifo
) 或 bash 的read
函数来执行某些操作?编辑:
也许只是将输出重定向到文件,然后您可以使用 PIPESTATUS:
xargs
is run in a child process, as are all the commands you call. So they can't effect the environment of your shell.You might be able to do something with named pipes (
mkfifo
), or possible bash'sread
function?EDIT:
Maybe just redirect the output to a file, then you can use PIPESTATUS:
怎么样...
How about ...
为什么不直接填充一个新数组呢?
Why not just populate a new array?
已经有一些有用的解决方案。事实证明,我实际上有一个与上面提出的问题相匹配的例子;无论如何,足够接近了。
考虑一下:
这意味着我的工作目录中有 3 个
.cpp
文件。现在$XX
是 3,我可以在我的脚本中使用该结果。这是人为的,因为在这个例子中我实际上并不需要 xargs。但它确实有效。在问题的示例中......
我认为这不会给您指定的内容。
exit
将在cat
被提及之前退出子 shell。另外,我可能会从类似
x
现在具有上一个命令的状态开始。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:
Meaning that I had 3 x
.cpp
files to in my working directory. Now$XX
is 3 and I can make use of that result in my script. It is contrived, because I don't actually need thexargs
in this example. It works though.In the example from the question ...
I don't think that will give you what was specified.
exit
will quit the sub-shell before thecat
gets a mention. Also on that note,I might start with something like
x
now has the status from the last command.将每一行输入分配给一个数组,例如目录中的所有python文件
,其中$9是ls -l中与文件名对应的第九个字段
Assign each line of input to an array, e.g. all python files in a directory
where $9 is the nineth field in ls -l corresponding to the filename