/bin/sh: read variable from pipe [duplicate]
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
This question already has an answer here:
in bash, read after a pipe is not setting values
2 answers
In bash
or zsh
, I can use following syntax to read from pipe into variables:
echo AAA BBB | read X Y ; echo $X
which will print AAA
Why does the same not work in /bin/sh
?
I am using /bin/sh
-> /bin/dash
in Debian
bash shell dash
marked as duplicate by muru, Jeff Schaller, sebasth, Shadur, Kiwy Sep 11 at 12:57
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |Â
up vote
1
down vote
favorite
This question already has an answer here:
in bash, read after a pipe is not setting values
2 answers
In bash
or zsh
, I can use following syntax to read from pipe into variables:
echo AAA BBB | read X Y ; echo $X
which will print AAA
Why does the same not work in /bin/sh
?
I am using /bin/sh
-> /bin/dash
in Debian
bash shell dash
marked as duplicate by muru, Jeff Schaller, sebasth, Shadur, Kiwy Sep 11 at 12:57
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
2
for me, it doesn't work inbash
either. Also, please clarify if you expect an answer forsh
ordash
.
â RoVo
Sep 11 at 7:06
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
This question already has an answer here:
in bash, read after a pipe is not setting values
2 answers
In bash
or zsh
, I can use following syntax to read from pipe into variables:
echo AAA BBB | read X Y ; echo $X
which will print AAA
Why does the same not work in /bin/sh
?
I am using /bin/sh
-> /bin/dash
in Debian
bash shell dash
This question already has an answer here:
in bash, read after a pipe is not setting values
2 answers
In bash
or zsh
, I can use following syntax to read from pipe into variables:
echo AAA BBB | read X Y ; echo $X
which will print AAA
Why does the same not work in /bin/sh
?
I am using /bin/sh
-> /bin/dash
in Debian
This question already has an answer here:
in bash, read after a pipe is not setting values
2 answers
bash shell dash
bash shell dash
edited Sep 11 at 8:36
franiis
1146
1146
asked Sep 11 at 6:41
Martin Vegter
61831113221
61831113221
marked as duplicate by muru, Jeff Schaller, sebasth, Shadur, Kiwy Sep 11 at 12:57
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by muru, Jeff Schaller, sebasth, Shadur, Kiwy Sep 11 at 12:57
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
2
for me, it doesn't work inbash
either. Also, please clarify if you expect an answer forsh
ordash
.
â RoVo
Sep 11 at 7:06
add a comment |Â
2
for me, it doesn't work inbash
either. Also, please clarify if you expect an answer forsh
ordash
.
â RoVo
Sep 11 at 7:06
2
2
for me, it doesn't work in
bash
either. Also, please clarify if you expect an answer for sh
or dash
.â RoVo
Sep 11 at 7:06
for me, it doesn't work in
bash
either. Also, please clarify if you expect an answer for sh
or dash
.â RoVo
Sep 11 at 7:06
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
3
down vote
Why does the same not work in '/bin/sh' ?
Assigning variables in a pipe does not work as expected in sh
and bash
because each command of a pipe runs in a subshell. Actually, the command does work, X
and Y
get declared, but they are not available outside the pipe.
The following will work:
echo AAA BBB | read X Y ; echo $X;
But in your case:
try this,
read X Y <<< "AAA BBB"
or
read X Y < <(echo "AAA BBB")
Some useful links:
- http://mywiki.wooledge.org/BashFAQ/024
- bash: Assign variable from pipe?
- Read values into a shell variable from a pipe
2
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
Thanks, I made it clear that this answer is forsh
. I don't usedash
, so someone else might help.
â RoVo
Sep 11 at 6:58
1
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
1
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
1
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
 |Â
show 4 more comments
up vote
2
down vote
in bash or zsh, I can use following syntax to read from pipe into variables.
echo AAA BBB | read X Y ; echo $X
No, you can't. Not in Bash with the default settings.
$ ./bash5.0-alpha -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=5.0.0(1)-alpha X=""
$ bash -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X=""
Bash runs all the commands in a pipeline in separate subshell environments, so the changes to shell variables aren't visible outside the pipeline. Dash is similar here.
Zsh and ksh (AT&T implementations, not pdksh
or derivatives) run the last command of the pipeline in the main shell environment, so there that works:
$ zsh -c 'echo AAA BBB | read X Y ; echo "Zsh=$ZSH_VERSION X="$X""'
Zsh=5.3.1 X="AAA"
In Bash, you can shopt -s lastpipe
to have it do what ksh and zsh do (only works in non-interactive shells though):
$ bash -O lastpipe -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X="AAA"
But I don't think there's such an option for Dash.
In Bash you could also use process substitution instead of the pipe, but that's not an option in Dash either.
The workarounds would revolve around making the right-hand side of the loop a compound statement or a function, and so using the value read from the pipe in the same environment it was read in.
$ dash -c 'echo AAA BBB | read X Y ; echo "X="$X""; '
X="AAA"
$ dash -c 'f() read X Y ; echo "X="$X""; ; echo AAA BBB | f'
X="AAA"
Or use a here document:
read X Y << EOF
$(echo AAA BBB)
EOF
add a comment |Â
up vote
0
down vote
No, this does not set X and Y (after the semicolon).
echo AAA BBB | read X Y ; echo $X
$ bash -c 'echo AAA BBB | read X Y ; echo "<$X>"'
<>
The same happens in dash.
To get it to work in dash you need to resort to older solutions (here-doc):
$ read X Y <<_EOT_
> AAA BBB
> _EOT_
$ echo "<$X>"
<AAA>
As a command to try shells (sadly the newlines can not be removed (no one-liner)):
$ bash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
That works exactly the same in dash, zsh, ksh, and many others:
$ dash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
Newer alternatives (that do not work in dash) to the here-doc
may be:
here-string (works in bash, ksh, zsh):
$ bash -c 'read X Y <<<"AAA BBB"; echo "<$X>" '
<AAA>Process substitution (works in bash, ksh, zsh):
$ bash -c 'read X Y < <(echo AAA BBB) ; echo "<$X>" '
<AAA>
An alternative that prints the value and works in dash, but does not keep the variable set in dash or bash (but does in ksh and zsh), is:
Group command:
$ dash -c 'echo "AAA BBB" | read X Y ; echo "<$X>"; ; echo "<$X>" '
<AAA>
<>Note that this last solution may be set to keep the variables set in bash with the
lastpipe
option (not for interactive use) or in ksh/zsh by default:$ bash -c 'shopt -s lastpipe;echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ ksh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ zsh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ; echo "2<$X>"'
1<AAA>
2<AAA>
Presumably, the OP is using thelastpipe
option inbash
. Trybash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
@StéphaneChazelas Yes, the user may use (may be using)lastpipe
, but I didn't read any confirmation of that. Details added anyway.
â Isaac
Sep 11 at 10:01
add a comment |Â
up vote
-3
down vote
Be careful with variable assignments from a process in a pipeline. The POSIX standard does not require a specific behavior.
Modern shells like ksh93
and recent versions of the Bourne Shell
let the main shell be the parent of both processes in your pipeline and in case the rightmost process is a builtin command, this command is even run in the main shell.
Another variant is to use the above method but to always run the rightmost command in another process.
The old version is how the original Bourne Shell worked: The shell forks and the forked process creates all other proceses from the pipe and finally converts into the rightmost process.
The last version needs a lot less code than the others but is slower. Because of the code size, this was used in 1976.
The first variant is the fastest variant but needs more code than the others, but it it the only variant that runs the variable assignment in the orginal shell process, which is required to have the modified variable value in the main shell.
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
Why does the same not work in '/bin/sh' ?
Assigning variables in a pipe does not work as expected in sh
and bash
because each command of a pipe runs in a subshell. Actually, the command does work, X
and Y
get declared, but they are not available outside the pipe.
The following will work:
echo AAA BBB | read X Y ; echo $X;
But in your case:
try this,
read X Y <<< "AAA BBB"
or
read X Y < <(echo "AAA BBB")
Some useful links:
- http://mywiki.wooledge.org/BashFAQ/024
- bash: Assign variable from pipe?
- Read values into a shell variable from a pipe
2
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
Thanks, I made it clear that this answer is forsh
. I don't usedash
, so someone else might help.
â RoVo
Sep 11 at 6:58
1
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
1
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
1
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
 |Â
show 4 more comments
up vote
3
down vote
Why does the same not work in '/bin/sh' ?
Assigning variables in a pipe does not work as expected in sh
and bash
because each command of a pipe runs in a subshell. Actually, the command does work, X
and Y
get declared, but they are not available outside the pipe.
The following will work:
echo AAA BBB | read X Y ; echo $X;
But in your case:
try this,
read X Y <<< "AAA BBB"
or
read X Y < <(echo "AAA BBB")
Some useful links:
- http://mywiki.wooledge.org/BashFAQ/024
- bash: Assign variable from pipe?
- Read values into a shell variable from a pipe
2
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
Thanks, I made it clear that this answer is forsh
. I don't usedash
, so someone else might help.
â RoVo
Sep 11 at 6:58
1
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
1
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
1
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
 |Â
show 4 more comments
up vote
3
down vote
up vote
3
down vote
Why does the same not work in '/bin/sh' ?
Assigning variables in a pipe does not work as expected in sh
and bash
because each command of a pipe runs in a subshell. Actually, the command does work, X
and Y
get declared, but they are not available outside the pipe.
The following will work:
echo AAA BBB | read X Y ; echo $X;
But in your case:
try this,
read X Y <<< "AAA BBB"
or
read X Y < <(echo "AAA BBB")
Some useful links:
- http://mywiki.wooledge.org/BashFAQ/024
- bash: Assign variable from pipe?
- Read values into a shell variable from a pipe
Why does the same not work in '/bin/sh' ?
Assigning variables in a pipe does not work as expected in sh
and bash
because each command of a pipe runs in a subshell. Actually, the command does work, X
and Y
get declared, but they are not available outside the pipe.
The following will work:
echo AAA BBB | read X Y ; echo $X;
But in your case:
try this,
read X Y <<< "AAA BBB"
or
read X Y < <(echo "AAA BBB")
Some useful links:
- http://mywiki.wooledge.org/BashFAQ/024
- bash: Assign variable from pipe?
- Read values into a shell variable from a pipe
edited Sep 11 at 8:48
answered Sep 11 at 6:48
RoVo
1,800213
1,800213
2
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
Thanks, I made it clear that this answer is forsh
. I don't usedash
, so someone else might help.
â RoVo
Sep 11 at 6:58
1
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
1
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
1
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
 |Â
show 4 more comments
2
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
Thanks, I made it clear that this answer is forsh
. I don't usedash
, so someone else might help.
â RoVo
Sep 11 at 6:58
1
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
1
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
1
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
2
2
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
for me, it is not working in bash (4.3.48).
â RoVo
Sep 11 at 6:53
Thanks, I made it clear that this answer is for
sh
. I don't use dash
, so someone else might help.â RoVo
Sep 11 at 6:58
Thanks, I made it clear that this answer is for
sh
. I don't use dash
, so someone else might help.â RoVo
Sep 11 at 6:58
1
1
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
"in Bash < 4.4"? Is there some reason to think that would work differently in Bash 4.4 or later?
â ilkkachu
Sep 11 at 8:16
1
1
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
@Stephen Kitt said earlier in a now deleted comment that the command works for him in 4.4.x. Also, OP reports that it works for him in bash. Unfortunately, I did not find sources for that...
â RoVo
Sep 11 at 8:19
1
1
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
IâÂÂm not sure what I was smoking earlier, the initial command doesnâÂÂt work for me on Bash 4.4 either now (and thereâÂÂs nothing in the changes from 4.3 to 4.4 which would explain the difference in behaviour).
â Stephen Kitt
Sep 11 at 8:47
 |Â
show 4 more comments
up vote
2
down vote
in bash or zsh, I can use following syntax to read from pipe into variables.
echo AAA BBB | read X Y ; echo $X
No, you can't. Not in Bash with the default settings.
$ ./bash5.0-alpha -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=5.0.0(1)-alpha X=""
$ bash -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X=""
Bash runs all the commands in a pipeline in separate subshell environments, so the changes to shell variables aren't visible outside the pipeline. Dash is similar here.
Zsh and ksh (AT&T implementations, not pdksh
or derivatives) run the last command of the pipeline in the main shell environment, so there that works:
$ zsh -c 'echo AAA BBB | read X Y ; echo "Zsh=$ZSH_VERSION X="$X""'
Zsh=5.3.1 X="AAA"
In Bash, you can shopt -s lastpipe
to have it do what ksh and zsh do (only works in non-interactive shells though):
$ bash -O lastpipe -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X="AAA"
But I don't think there's such an option for Dash.
In Bash you could also use process substitution instead of the pipe, but that's not an option in Dash either.
The workarounds would revolve around making the right-hand side of the loop a compound statement or a function, and so using the value read from the pipe in the same environment it was read in.
$ dash -c 'echo AAA BBB | read X Y ; echo "X="$X""; '
X="AAA"
$ dash -c 'f() read X Y ; echo "X="$X""; ; echo AAA BBB | f'
X="AAA"
Or use a here document:
read X Y << EOF
$(echo AAA BBB)
EOF
add a comment |Â
up vote
2
down vote
in bash or zsh, I can use following syntax to read from pipe into variables.
echo AAA BBB | read X Y ; echo $X
No, you can't. Not in Bash with the default settings.
$ ./bash5.0-alpha -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=5.0.0(1)-alpha X=""
$ bash -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X=""
Bash runs all the commands in a pipeline in separate subshell environments, so the changes to shell variables aren't visible outside the pipeline. Dash is similar here.
Zsh and ksh (AT&T implementations, not pdksh
or derivatives) run the last command of the pipeline in the main shell environment, so there that works:
$ zsh -c 'echo AAA BBB | read X Y ; echo "Zsh=$ZSH_VERSION X="$X""'
Zsh=5.3.1 X="AAA"
In Bash, you can shopt -s lastpipe
to have it do what ksh and zsh do (only works in non-interactive shells though):
$ bash -O lastpipe -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X="AAA"
But I don't think there's such an option for Dash.
In Bash you could also use process substitution instead of the pipe, but that's not an option in Dash either.
The workarounds would revolve around making the right-hand side of the loop a compound statement or a function, and so using the value read from the pipe in the same environment it was read in.
$ dash -c 'echo AAA BBB | read X Y ; echo "X="$X""; '
X="AAA"
$ dash -c 'f() read X Y ; echo "X="$X""; ; echo AAA BBB | f'
X="AAA"
Or use a here document:
read X Y << EOF
$(echo AAA BBB)
EOF
add a comment |Â
up vote
2
down vote
up vote
2
down vote
in bash or zsh, I can use following syntax to read from pipe into variables.
echo AAA BBB | read X Y ; echo $X
No, you can't. Not in Bash with the default settings.
$ ./bash5.0-alpha -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=5.0.0(1)-alpha X=""
$ bash -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X=""
Bash runs all the commands in a pipeline in separate subshell environments, so the changes to shell variables aren't visible outside the pipeline. Dash is similar here.
Zsh and ksh (AT&T implementations, not pdksh
or derivatives) run the last command of the pipeline in the main shell environment, so there that works:
$ zsh -c 'echo AAA BBB | read X Y ; echo "Zsh=$ZSH_VERSION X="$X""'
Zsh=5.3.1 X="AAA"
In Bash, you can shopt -s lastpipe
to have it do what ksh and zsh do (only works in non-interactive shells though):
$ bash -O lastpipe -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X="AAA"
But I don't think there's such an option for Dash.
In Bash you could also use process substitution instead of the pipe, but that's not an option in Dash either.
The workarounds would revolve around making the right-hand side of the loop a compound statement or a function, and so using the value read from the pipe in the same environment it was read in.
$ dash -c 'echo AAA BBB | read X Y ; echo "X="$X""; '
X="AAA"
$ dash -c 'f() read X Y ; echo "X="$X""; ; echo AAA BBB | f'
X="AAA"
Or use a here document:
read X Y << EOF
$(echo AAA BBB)
EOF
in bash or zsh, I can use following syntax to read from pipe into variables.
echo AAA BBB | read X Y ; echo $X
No, you can't. Not in Bash with the default settings.
$ ./bash5.0-alpha -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=5.0.0(1)-alpha X=""
$ bash -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X=""
Bash runs all the commands in a pipeline in separate subshell environments, so the changes to shell variables aren't visible outside the pipeline. Dash is similar here.
Zsh and ksh (AT&T implementations, not pdksh
or derivatives) run the last command of the pipeline in the main shell environment, so there that works:
$ zsh -c 'echo AAA BBB | read X Y ; echo "Zsh=$ZSH_VERSION X="$X""'
Zsh=5.3.1 X="AAA"
In Bash, you can shopt -s lastpipe
to have it do what ksh and zsh do (only works in non-interactive shells though):
$ bash -O lastpipe -c 'echo AAA BBB | read X Y ; echo "Bash=$BASH_VERSION X="$X""'
Bash=4.4.12(1)-release X="AAA"
But I don't think there's such an option for Dash.
In Bash you could also use process substitution instead of the pipe, but that's not an option in Dash either.
The workarounds would revolve around making the right-hand side of the loop a compound statement or a function, and so using the value read from the pipe in the same environment it was read in.
$ dash -c 'echo AAA BBB | read X Y ; echo "X="$X""; '
X="AAA"
$ dash -c 'f() read X Y ; echo "X="$X""; ; echo AAA BBB | f'
X="AAA"
Or use a here document:
read X Y << EOF
$(echo AAA BBB)
EOF
edited Sep 11 at 9:53
Stéphane Chazelas
286k53528867
286k53528867
answered Sep 11 at 8:27
ilkkachu
52.2k679144
52.2k679144
add a comment |Â
add a comment |Â
up vote
0
down vote
No, this does not set X and Y (after the semicolon).
echo AAA BBB | read X Y ; echo $X
$ bash -c 'echo AAA BBB | read X Y ; echo "<$X>"'
<>
The same happens in dash.
To get it to work in dash you need to resort to older solutions (here-doc):
$ read X Y <<_EOT_
> AAA BBB
> _EOT_
$ echo "<$X>"
<AAA>
As a command to try shells (sadly the newlines can not be removed (no one-liner)):
$ bash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
That works exactly the same in dash, zsh, ksh, and many others:
$ dash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
Newer alternatives (that do not work in dash) to the here-doc
may be:
here-string (works in bash, ksh, zsh):
$ bash -c 'read X Y <<<"AAA BBB"; echo "<$X>" '
<AAA>Process substitution (works in bash, ksh, zsh):
$ bash -c 'read X Y < <(echo AAA BBB) ; echo "<$X>" '
<AAA>
An alternative that prints the value and works in dash, but does not keep the variable set in dash or bash (but does in ksh and zsh), is:
Group command:
$ dash -c 'echo "AAA BBB" | read X Y ; echo "<$X>"; ; echo "<$X>" '
<AAA>
<>Note that this last solution may be set to keep the variables set in bash with the
lastpipe
option (not for interactive use) or in ksh/zsh by default:$ bash -c 'shopt -s lastpipe;echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ ksh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ zsh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ; echo "2<$X>"'
1<AAA>
2<AAA>
Presumably, the OP is using thelastpipe
option inbash
. Trybash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
@StéphaneChazelas Yes, the user may use (may be using)lastpipe
, but I didn't read any confirmation of that. Details added anyway.
â Isaac
Sep 11 at 10:01
add a comment |Â
up vote
0
down vote
No, this does not set X and Y (after the semicolon).
echo AAA BBB | read X Y ; echo $X
$ bash -c 'echo AAA BBB | read X Y ; echo "<$X>"'
<>
The same happens in dash.
To get it to work in dash you need to resort to older solutions (here-doc):
$ read X Y <<_EOT_
> AAA BBB
> _EOT_
$ echo "<$X>"
<AAA>
As a command to try shells (sadly the newlines can not be removed (no one-liner)):
$ bash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
That works exactly the same in dash, zsh, ksh, and many others:
$ dash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
Newer alternatives (that do not work in dash) to the here-doc
may be:
here-string (works in bash, ksh, zsh):
$ bash -c 'read X Y <<<"AAA BBB"; echo "<$X>" '
<AAA>Process substitution (works in bash, ksh, zsh):
$ bash -c 'read X Y < <(echo AAA BBB) ; echo "<$X>" '
<AAA>
An alternative that prints the value and works in dash, but does not keep the variable set in dash or bash (but does in ksh and zsh), is:
Group command:
$ dash -c 'echo "AAA BBB" | read X Y ; echo "<$X>"; ; echo "<$X>" '
<AAA>
<>Note that this last solution may be set to keep the variables set in bash with the
lastpipe
option (not for interactive use) or in ksh/zsh by default:$ bash -c 'shopt -s lastpipe;echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ ksh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ zsh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ; echo "2<$X>"'
1<AAA>
2<AAA>
Presumably, the OP is using thelastpipe
option inbash
. Trybash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
@StéphaneChazelas Yes, the user may use (may be using)lastpipe
, but I didn't read any confirmation of that. Details added anyway.
â Isaac
Sep 11 at 10:01
add a comment |Â
up vote
0
down vote
up vote
0
down vote
No, this does not set X and Y (after the semicolon).
echo AAA BBB | read X Y ; echo $X
$ bash -c 'echo AAA BBB | read X Y ; echo "<$X>"'
<>
The same happens in dash.
To get it to work in dash you need to resort to older solutions (here-doc):
$ read X Y <<_EOT_
> AAA BBB
> _EOT_
$ echo "<$X>"
<AAA>
As a command to try shells (sadly the newlines can not be removed (no one-liner)):
$ bash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
That works exactly the same in dash, zsh, ksh, and many others:
$ dash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
Newer alternatives (that do not work in dash) to the here-doc
may be:
here-string (works in bash, ksh, zsh):
$ bash -c 'read X Y <<<"AAA BBB"; echo "<$X>" '
<AAA>Process substitution (works in bash, ksh, zsh):
$ bash -c 'read X Y < <(echo AAA BBB) ; echo "<$X>" '
<AAA>
An alternative that prints the value and works in dash, but does not keep the variable set in dash or bash (but does in ksh and zsh), is:
Group command:
$ dash -c 'echo "AAA BBB" | read X Y ; echo "<$X>"; ; echo "<$X>" '
<AAA>
<>Note that this last solution may be set to keep the variables set in bash with the
lastpipe
option (not for interactive use) or in ksh/zsh by default:$ bash -c 'shopt -s lastpipe;echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ ksh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ zsh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ; echo "2<$X>"'
1<AAA>
2<AAA>
No, this does not set X and Y (after the semicolon).
echo AAA BBB | read X Y ; echo $X
$ bash -c 'echo AAA BBB | read X Y ; echo "<$X>"'
<>
The same happens in dash.
To get it to work in dash you need to resort to older solutions (here-doc):
$ read X Y <<_EOT_
> AAA BBB
> _EOT_
$ echo "<$X>"
<AAA>
As a command to try shells (sadly the newlines can not be removed (no one-liner)):
$ bash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
That works exactly the same in dash, zsh, ksh, and many others:
$ dash -c 'read X Y <<_EOT_
AAA BBB
_EOT_
echo "<$X>" '
<AAA>
Newer alternatives (that do not work in dash) to the here-doc
may be:
here-string (works in bash, ksh, zsh):
$ bash -c 'read X Y <<<"AAA BBB"; echo "<$X>" '
<AAA>Process substitution (works in bash, ksh, zsh):
$ bash -c 'read X Y < <(echo AAA BBB) ; echo "<$X>" '
<AAA>
An alternative that prints the value and works in dash, but does not keep the variable set in dash or bash (but does in ksh and zsh), is:
Group command:
$ dash -c 'echo "AAA BBB" | read X Y ; echo "<$X>"; ; echo "<$X>" '
<AAA>
<>Note that this last solution may be set to keep the variables set in bash with the
lastpipe
option (not for interactive use) or in ksh/zsh by default:$ bash -c 'shopt -s lastpipe;echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ ksh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ;echo "2<$X>"'
1<AAA>
2<AAA>
$ zsh -c 'echo "AAA BBB"| read X Y;echo "1<$X>"; ; echo "2<$X>"'
1<AAA>
2<AAA>
edited Sep 11 at 11:05
ctrl-alt-delor
9,20431948
9,20431948
answered Sep 11 at 9:43
Isaac
7,28911035
7,28911035
Presumably, the OP is using thelastpipe
option inbash
. Trybash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
@StéphaneChazelas Yes, the user may use (may be using)lastpipe
, but I didn't read any confirmation of that. Details added anyway.
â Isaac
Sep 11 at 10:01
add a comment |Â
Presumably, the OP is using thelastpipe
option inbash
. Trybash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
@StéphaneChazelas Yes, the user may use (may be using)lastpipe
, but I didn't read any confirmation of that. Details added anyway.
â Isaac
Sep 11 at 10:01
Presumably, the OP is using the
lastpipe
option in bash
. Try bash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
Presumably, the OP is using the
lastpipe
option in bash
. Try bash -O lastpipe -c 'echo AAA BBB | read X Y; echo "<$X>"'
â Stéphane Chazelas
Sep 11 at 9:50
@StéphaneChazelas Yes, the user may use (may be using)
lastpipe
, but I didn't read any confirmation of that. Details added anyway.â Isaac
Sep 11 at 10:01
@StéphaneChazelas Yes, the user may use (may be using)
lastpipe
, but I didn't read any confirmation of that. Details added anyway.â Isaac
Sep 11 at 10:01
add a comment |Â
up vote
-3
down vote
Be careful with variable assignments from a process in a pipeline. The POSIX standard does not require a specific behavior.
Modern shells like ksh93
and recent versions of the Bourne Shell
let the main shell be the parent of both processes in your pipeline and in case the rightmost process is a builtin command, this command is even run in the main shell.
Another variant is to use the above method but to always run the rightmost command in another process.
The old version is how the original Bourne Shell worked: The shell forks and the forked process creates all other proceses from the pipe and finally converts into the rightmost process.
The last version needs a lot less code than the others but is slower. Because of the code size, this was used in 1976.
The first variant is the fastest variant but needs more code than the others, but it it the only variant that runs the variable assignment in the orginal shell process, which is required to have the modified variable value in the main shell.
add a comment |Â
up vote
-3
down vote
Be careful with variable assignments from a process in a pipeline. The POSIX standard does not require a specific behavior.
Modern shells like ksh93
and recent versions of the Bourne Shell
let the main shell be the parent of both processes in your pipeline and in case the rightmost process is a builtin command, this command is even run in the main shell.
Another variant is to use the above method but to always run the rightmost command in another process.
The old version is how the original Bourne Shell worked: The shell forks and the forked process creates all other proceses from the pipe and finally converts into the rightmost process.
The last version needs a lot less code than the others but is slower. Because of the code size, this was used in 1976.
The first variant is the fastest variant but needs more code than the others, but it it the only variant that runs the variable assignment in the orginal shell process, which is required to have the modified variable value in the main shell.
add a comment |Â
up vote
-3
down vote
up vote
-3
down vote
Be careful with variable assignments from a process in a pipeline. The POSIX standard does not require a specific behavior.
Modern shells like ksh93
and recent versions of the Bourne Shell
let the main shell be the parent of both processes in your pipeline and in case the rightmost process is a builtin command, this command is even run in the main shell.
Another variant is to use the above method but to always run the rightmost command in another process.
The old version is how the original Bourne Shell worked: The shell forks and the forked process creates all other proceses from the pipe and finally converts into the rightmost process.
The last version needs a lot less code than the others but is slower. Because of the code size, this was used in 1976.
The first variant is the fastest variant but needs more code than the others, but it it the only variant that runs the variable assignment in the orginal shell process, which is required to have the modified variable value in the main shell.
Be careful with variable assignments from a process in a pipeline. The POSIX standard does not require a specific behavior.
Modern shells like ksh93
and recent versions of the Bourne Shell
let the main shell be the parent of both processes in your pipeline and in case the rightmost process is a builtin command, this command is even run in the main shell.
Another variant is to use the above method but to always run the rightmost command in another process.
The old version is how the original Bourne Shell worked: The shell forks and the forked process creates all other proceses from the pipe and finally converts into the rightmost process.
The last version needs a lot less code than the others but is slower. Because of the code size, this was used in 1976.
The first variant is the fastest variant but needs more code than the others, but it it the only variant that runs the variable assignment in the orginal shell process, which is required to have the modified variable value in the main shell.
answered Sep 11 at 7:45
schily
9,64131537
9,64131537
add a comment |Â
add a comment |Â
2
for me, it doesn't work in
bash
either. Also, please clarify if you expect an answer forsh
ordash
.â RoVo
Sep 11 at 7:06