Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <409A4817.5010001@ecs.soton.ac.uk> Date: Thu, 06 May 2004 15:13:43 +0100 From: Andy Rushton Organization: Southampton University User-Agent: Mozilla Thunderbird 0.5 (Windows/20040207) MIME-Version: 1.0 To: Kevan Gelling CC: Cygwin mailing list Subject: Re: 1.5.9: Trouble with setting variables using 'read' in a script References: <201BC46BD93D244AB0A910D1203FFC1904B6A873 AT ecexchange02 DOT euphony DOT com> In-Reply-To: <201BC46BD93D244AB0A910D1203FFC1904B6A873@ecexchange02.euphony.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-MailScanner-Information: Please contact helpdesk AT ecs DOT soton DOT ac DOT uk for more information X-ECS-MailScanner: Found to be clean X-IsSubscribed: yes Kevan Gelling wrote: >I'm having trouble setting variables using the 'read' command in bash. > >All of the following lines fail to set $var and return a blank line. > - echo "text" | read var ; echo $var > - cat file | read var ; echo $var > - read var < file | echo $var > > The problem is that the pipeline is executed by spawning a sub-process and running a sub-shell in it. The variable that is being read into is actually a copy that exists within that sub-shell, not the original that you declared in the script. Variables set in sub-shells cannot be passed back to their parent shell (the script itself). >I can get it work by explicitly declaring the file descriptor with the file >redirection, but I'd prefer to use a pipe. > - read -u 0 var > This doesn't create a sub-shell, so the variable being read is the one in the script. >Another related quirk, is that variables set within 'while read' loops lose >their values once the loop ends. The following example displays "text text" >within the loop and blank line outside. > - echo "text" |\ > while read > do > foo=$REPLY ; bar="text" > echo $foo $bar > done > echo $foo $bar > > The while loop also becomes a sub-shell. Same problem as the pipeline. This is a 'feature' of bash and indeed all Bourne-shell derivatives. It makes a lot of shell features much harder to use than you would expect. Incidentally, this is why you cannot write shell scripts to change your environment. The script runs in a sub-shell, changes the local copy of the environment and then discards the local copy on exit leaving the parent shell in the same state as it was in before. Andy -- Andy Rushton, Southampton, UK We may eventually come to realize that chastity is no more a virtue than malnutrition. -- Alex Comfort -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/