piped input
The simplest method to set a variable is to read
it:
seq 3 | read -d '' x
Will also work in zsh
but not in ksh
(no NUL
allowed for the -d
option in ksh).
One way to use the value of x
is to do so in the subshell created by the pipe:
$ seq 3 | { read -d '' x; echo "$x"; }
1
2
3
Note that the exit condition of read is of failure (because no '' character was found). More details could be found in Bash FAQ 24
In ksh and zsh the value could be used after the pipe has ended (using a char that is not in the input (but not NUL) to make ksh also work):
$ seq 3 | read -d ':' x
$ echo "$x"
1
2
3
That's because, originally in ksh (later in zsh) the last command on a pipe would run in the same process as the parent shell, keeping the value of the variable changed after the pipe has ended.
One way to emulate this capacity in bash is to use lastpipe
(which will only work if JOB CONTROL is disabled (inside a non-interactive script or with set +m
)):
$ set +m; shopt -s lastpipe
$ seq 3 | read -d '' x
$ echo "$x"
1
2
3
Capture command output
Using Process Substitution :
$ read -d '' x < <(seq 3)
$ echo "$x"
1
2
3
Or, using the old here-doc:
$ read -d '' x <<-Hello
> $(seq 3)
> Hello
$ echo "$x"
1
2
3
Or, using printf:
$ printf -v x "$(seq 3)"
$ echo "$x"
1
2
3