From owner-freebsd-bugs Sun Jan 14 2:50:21 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 28A2137B400 for ; Sun, 14 Jan 2001 02:50:03 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f0EAo3g40290; Sun, 14 Jan 2001 02:50:03 -0800 (PST) (envelope-from gnats) Date: Sun, 14 Jan 2001 02:50:03 -0800 (PST) Message-Id: <200101141050.f0EAo3g40290@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Peter Pentchev Subject: Re: bin/24228: /bin/sh problem : variable after pipeline won't be set Reply-To: Peter Pentchev Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/24228; it has been noted by GNATS. From: Peter Pentchev To: imura@af.airnet.ne.jp Cc: FreeBSD-gnats-submit@freebsd.org Subject: Re: bin/24228: /bin/sh problem : variable after pipeline won't be set Date: Sun, 14 Jan 2001 12:47:51 +0200 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? To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message