Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read values into a shell variable from a pipe

Tags:

linux

bash

pipe

People also ask

How do you pipe the output of a command to a variable?

To store the output of a command in a variable, you can use the shell command substitution feature in the forms below: variable_name=$(command) variable_name=$(command [option ...] arg1 arg2 ...) OR variable_name='command' variable_name='command [option ...]

How do you pass a variable into a shell script?

In a shell script, you can pass variables as arguments by entering arguments after the script name, for example ./script.sh arg1 arg2 . The shell automatically assigns each argument name to a variable. Arguments are set of characters between spaces added after the script.


Use

IFS= read var << EOF
$(foo)
EOF

You can trick read into accepting from a pipe like this:

echo "hello world" | { read test; echo test=$test; }

or even write a function like this:

read_from_pipe() { read "$@" <&0; }

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.


if you want to read in lots of data and work on each line separately you could use something like this:

cat myFile | while read x ; do echo $x ; done

if you want to split the lines up into multiple words you can use multiple variables in place of x like this:

cat myFile | while read x y ; do echo $y $x ; done

alternatively:

while read x y ; do echo $y $x ; done < myFile

But as soon as you start to want to do anything really clever with this sort of thing you're better going for some scripting language like perl where you could try something like this:

perl -ane 'print "$F[0]\n"' < myFile

There's a fairly steep learning curve with perl (or I guess any of these languages) but you'll find it a lot easier in the long run if you want to do anything but the simplest of scripts. I'd recommend the Perl Cookbook and, of course, The Perl Programming Language by Larry Wall et al.


This is another option

$ read test < <(echo hello world)

$ echo $test
hello world

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:

$ read a b c <<< $(echo 1 2 3)
$ echo $a $b $c
1 2 3

But see @chepner's answer for information about lastpipe.


I'm no expert in Bash, but I wonder why this hasn't been proposed:

stdin=$(cat)

echo "$stdin"

One-liner proof that it works for me:

$ fortune | eval 'stdin=$(cat); echo "$stdin"'