I am trying to get bash to process data from stdin that gets piped into, but no luck. What I mean is none of the following work:
echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=
echo "hello world" | read test; echo test=$test
test=
echo "hello world" | test=`cat`; echo test=$test
test=
where I want the output to be test=hello world
. I've tried putting "" quotes around "$test"
that doesn't work either.
I think you were trying to write a shell script which could take input from stdin. but while you are trying it to do it inline, you got lost trying to create that test= variable. I think it does not make much sense to do it inline, and that's why it does not work the way you expect.
I was trying to reduce
to get a specific line from various input. so I could type...
so I need a small shell program able to read from stdin. like you do.
there you go.
I'm no expert in Bash, but I wonder why this hasn't been proposed:
One-liner proof that it works for me:
Use
You can trick
read
into accepting from a pipe like this:or even write a function like this:
But there's no point - your variable assignments may not last! A pipeline may spawn a subshell, where the environment is inherited by value, not by reference. This is why
read
doesn't bother with input from a pipe - it's undefined.FYI, http://www.etalabs.net/sh_tricks.html is a nifty collection of the cruft necessary to fight the oddities and incompatibilities of bourne shells, sh.
The first attempt was pretty close. This variation should work:
and the output is:
You need braces after the pipe to enclose the assignment to test and the echo.
Without the braces, the assignment to test (after the pipe) is in one shell, and the echo "test=$test" is in a separate shell which doesn't know about that assignment. That's why you were getting "test=" in the output instead of "test=hello world".
bash
4.2 introduces thelastpipe
option, which allows your code to work as written, by executing the last command in a pipeline in the current shell, rather than a subshell.read
won't read from a pipe (or possibly the result is lost because the pipe creates a subshell). You can, however, use a here string in Bash: