| Summary: | when using /bin/sh, setting variable after pipeline won't work | ||
|---|---|---|---|
| Product: | Base System | Reporter: | imura <imura> |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.2-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
|
Description
imura
2001-01-10 16:40:00 UTC
On Thu, Jan 11, 2001 at 01:32:48AM +0900, imura@af.airnet.ne.jp wrote: > > >Number: 24228 > >Category: bin > >Synopsis: when using /bin/sh, setting variable after pipeline won't work > >Originator: Ryuichiro Imura > >Release: FreeBSD 4.2-STABLE i386 > >Environment: > > FreeBSD 4.2-STABLE > > >Description: > > When using /bin/sh, setting variables after "|" > (in other words, I mean setting variables in a pipeline sequence), > will be ignored out of the pipeline sequence. > > If it is a definition of /bin/sh, it's ok, I'm sorry, > otherwise I think it should be fixed. AFAIK, yes, this is expected sh(1) behavior. From the manpage: Note that unlike some other shells, sh executes each process in the pipeline as a child of the sh process. Shell builtin commands are the exception to this rule. They are executed in the current shell, although they do not affect its environment when used in pipelines. That is, sh(1) forks a subshell for each subsequent command/construct in the pipe, and variable assignments within a construct are only valid for the subshell that construct is executing in, and not back-propagated to the main shell. Thus, in your example, 'variable' would only be set to 'bar' for the subshell executing the while loop. See below for a suggestion for a workaround. > >How-To-Repeat: > > write a simple shell script like this: > -----------starts here---------- > #/bin/sh > > cat FILE | while read line ; do > if [ $line = foo ]; then > variable=bar > fi > echo $variable <---- this will be printed > done > > echo $variable <---- this will NOT be printed > -----------ends here------------ You may do better with something like the following: #!/bin/sh # (make sure that's #!, not just # ;) exec < FILE while read line; do if [ "$line" = "foo" ]; then variable="bar" fi echo "line is $line, variable is $variable" done echo "after the loop, variable is $variable" Hope that makes things clearer :) G'luck, Peter -- Hey, out there - is it *you* reading me, or is it someone else? On Sun, Jan 14, 2001 at 12:47:51PM +0200, Peter Pentchev wrote:
> AFAIK, yes, this is expected sh(1) behavior. From the manpage:
>
> Note that unlike some other shells, sh executes each process in the
> pipeline as a child of the sh process. Shell builtin commands are the
> exception to this rule. They are executed in the current shell, although
> they do not affect its environment when used in pipelines.
>
> That is, sh(1) forks a subshell for each subsequent command/construct
> in the pipe, and variable assignments within a construct are only valid
> for the subshell that construct is executing in, and not back-propagated
> to the main shell.
>
> Thus, in your example, 'variable' would only be set to 'bar' for
> the subshell executing the while loop. See below for a suggestion
> for a workaround.
Thanks very much for your explanation. I got it. :)
So, please close this PR.
- R. Imura
State Changed From-To: open->closed Satisfactory explaination provided by Peter Pentchev. |