Date: Sun, 17 Aug 2008 20:45:31 -0700 From: David Wolfskill <david@catwhisker.org> To: Giorgos Keramidas <keramida@ceid.upatras.gr> Cc: freebsd-questions@freebsd.org Subject: Re: Shell scripts: variable assignment within read loops Message-ID: <20080818034531.GZ44815@bunrab.catwhisker.org> In-Reply-To: <87ljyvypa8.fsf@kobe.laptop> References: <20080818013328.GY44815@bunrab.catwhisker.org> <87ljyvypa8.fsf@kobe.laptop>
next in thread | previous in thread | raw e-mail | index | archive | help
--fx1QzQyU29xyWDn1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Aug 18, 2008 at 06:29:03AM +0300, Giorgos Keramidas wrote: > ... > You are right that feeding data to a looping construct through a pipe > may run in a subshell. The ``Single UNIX Specification'' says > .... Ah; thanks for the confirmation. =20 >... > What I usually do in similar shell scripts is something like: >=20 > cat "${filename}" | sed -n -e '/foo/ s/bar/baz/' | \ > xargs -n1 blah >=20 > This isn't exactly the same as assigning $foo to the results of the > loop, but you can also use: >=20 > foo=3D`cat $filename | while read bar ; do \ > stuff ... > echo "$bar" > more stuff... > done` Right; I had seen that type of construct in /etc/rc.d.* (which is where I often look for samples of shell scripts that need to work reliably). As you noticed, that won't quite do for what I'm trying to accomplish here. > ... > > As you see, I am circumventing the issue by writing to a transient > > file. In the intended application, the script is to be used to gather > > resource-utilization information; thus, I want its "footprint" to be > > smaller, rather than larger. Granted, in my case, I would be writing > > a tiny text file to a swap-backed tmpfs, but in production, I won't > > have the luxury of knowing that in advance: the intent is that the > > script must run on a minimal FreeBSD system, with no "ports" or other > > 3rd-party software installed. > > > > Is there some other -- possibly better -- way to do this (using Bourne > > shell scripting)? >=20 > Ah, that's much better. Now I see what you are trying to do. :-) > Would you be ok with an awk(1) script instead of /bin/sh? It tends > to be nicer for this sort of thing, i.e.: Yes, awk(1) would be OK. I'll be more inclined to use it if I can figure out a way to use it instead of sed(1) for a very different part of the script. :-} > $ expand david.awk | cat -n > 1 # > 2 # Gather the field names if this is a header-line. > 3 # > 4 $0 ~ /^Name/ { > 5 for (k =3D 1; k <=3D NF; k++) > 6 tag[k] =3D $k; > 7 } > 8 > 9 # > 10 # For all other lines, just print the tagged field values. > 11 # > 12 $0 !~ /^Name/ { > 13 name =3D $1; > 14 for (k =3D 1; k <=3D NF; k++) { > 15 if ($k =3D=3D "-") > 16 $k =3D "0"; > 17 printf "%s_%s: %s\n", tag[k], name, $k; > 18 } > 19 } >=20 > $ netstat -nibd -f inet | awk -f david.awk > Name_re0: re0 > Mtu_re0: 1500 > Network_re0: 192.168.1.0/2 > ... Very cool; thank you very much! I will study that a bit.... (I'd normally do this stuff in Perl, but in addition to the other issues mentioned earlier, the script will be sleeping most of the time, but wake up & spit out results periodically. The usual case will be every 5 minutes, but I plan to make use of it with radically shorter periods in certain specialized environments -- such as every 5 seconds. And I still want it to be low overhead. I also note in passing that in its "production" environments, the script's standard output will be redirected to append to a file on a different machine via an SSH tunnel.) > With a bit of preprocessing, it may be possible to extract the network > names and print the "(end) NICs: XXX XXX" part too. Right -- much of the output I demonstrated was strictly for debugging/ expository purposes. Thanks again, Giorgos! Peace, david --=20 David H. Wolfskill david@catwhisker.org Depriving a girl or boy of an opportunity for education is evil. See http://www.catwhisker.org/~david/publickey.gpg for my public key. --fx1QzQyU29xyWDn1 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (FreeBSD) iEYEARECAAYFAkio8FoACgkQmprOCmdXAD3GdQCfUjQnskJmIH4Y0vPZmpDEgowb Bo8AnA+W7KVKPGH3+rFUurVp+W/zvwHK =tQNG -----END PGP SIGNATURE----- --fx1QzQyU29xyWDn1--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080818034531.GZ44815>