Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using xargs to assign stdin to a variable

Tags:

bash

pipe

xargs

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.

like image 915
User1 Avatar asked Aug 10 '10 16:08

User1


2 Answers

When you use backticks (or the preferred $()) you're running those commands in a subshell. The PIPESTATUS 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 $?.

like image 121
Dennis Williamson Avatar answered Oct 17 '22 19:10

Dennis Williamson


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's read function?

EDIT:

Maybe just redirect the output to a file, then you can use PIPESTATUS:

command1 | command2 | command3 >/tmp/tmpfile
## Examine PIPESTATUS
X=$(cat /tmp/tmpfile)
like image 22
Douglas Leeder Avatar answered Oct 17 '22 20:10

Douglas Leeder