From owner-freebsd-questions@FreeBSD.ORG Tue Aug 19 13:54:05 2008 Return-Path: Delivered-To: freebsd-questions@FreeBSD.ORG Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 85E01106566C for ; Tue, 19 Aug 2008 13:54:05 +0000 (UTC) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (lurza.secnetix.de [212.17.241.230]) by mx1.freebsd.org (Postfix) with ESMTP id F3FEE8FC18 for ; Tue, 19 Aug 2008 13:54:04 +0000 (UTC) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (localhost [127.0.0.1]) by lurza.secnetix.de (8.14.1/8.14.1) with ESMTP id m7JDquev010207; Tue, 19 Aug 2008 15:53:07 +0200 (CEST) (envelope-from oliver.fromme@secnetix.de) Received: (from olli@localhost) by lurza.secnetix.de (8.14.1/8.14.1/Submit) id m7JDqkQA010206; Tue, 19 Aug 2008 15:52:46 +0200 (CEST) (envelope-from olli) Date: Tue, 19 Aug 2008 15:52:46 +0200 (CEST) Message-Id: <200808191352.m7JDqkQA010206@lurza.secnetix.de> From: Oliver Fromme To: freebsd-questions@FreeBSD.ORG, David Wolfskill In-Reply-To: <20080818013328.GY44815@bunrab.catwhisker.org> X-Newsgroups: list.freebsd-questions User-Agent: tin/1.8.3-20070201 ("Scotasay") (UNIX) (FreeBSD/6.2-STABLE-20070808 (i386)) MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.1.2 (lurza.secnetix.de [127.0.0.1]); Tue, 19 Aug 2008 15:53:07 +0200 (CEST) Cc: Subject: Re: Shell scripts: variable assignment within read loops X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: freebsd-questions@FreeBSD.ORG, David Wolfskill List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Aug 2008 13:54:05 -0000 David Wolfskill wrote: > I am writing a (Bourne) shell script that is intended (among other > things) to obtain information from a command, such as: > > netstat -nibd -f inet > > by reading and parsing the output. > > However, the "obvious" (to me) approach of piping the output of the > command to the standard input of a "while read ..." statement turns out > to be not very useful; > [...] > Well, that's not *quite* accurate:the assignment is done all right, but > in the latter case, it appears to be done in a subshell, so by the time > we get to the "echo" statement, any variable assignments from within the > read loop have vanished. That's correct, as Giorgos has already pointed out. Most bourne shells execute all parts of a pipe except the first one in a subshell, so any assignments are lost. A common way is to echo things from within the subshell and capture them through command expansion, like this: foo=$( something | while read x; do whatever echo "value" done ) That will assign "value" to the variable foo. This only works for single variables, of course. If you want to assign to multiple variables, it gets a little more tricky. One way is to use single assignment like above, and then split it into several variables on a delimiter character. The following will split $foo on whitespace and assign the results to $1, $2, $3 etc., with the count in $#: set -- $foo You can split on any other character by setting the IFS variable of the shell appropriately. If you know in advance how many values you'll get, another possibility is to use a so-called "here document": read foo1 foo2 foo3 rest <