From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from hawkwind.utcs.toronto.edu ([128.100.102.51]) by archone.tamu.edu with SMTP id <18983>; Wed, 11 Dec 1991 13:29:31 -0600 Received: from localhost by hawkwind.utcs.toronto.edu with SMTP id <2716>; Wed, 11 Dec 1991 14:28:29 -0500 To: The rc user community Subject: Re: A lighter read function In-reply-to: david's message of Wed, 11 Dec 91 07:28:26 -0500. <22832.692454506@golem.UUCP> Date: Wed, 11 Dec 1991 13:28:23 -0600 From: Chris Siebenmann Message-Id: <91Dec11.142829est.2716@hawkwind.utcs.toronto.edu> This has come up before on the mailing list. One cannot use sed, awk, or handgrown alternatives that use stdio when you are not reading from a terminal, because their buffering will eat too much of the input stream and then silently discard it when they exit. You can convince yourself by defining read in terms of one of them and then doing: {echo A; echo B} | {read a; echo a $a; read b; echo b $b} and noticing what comes out. line is safe, and trivial to write; I will happily mail my version to anyone who wants it. It even comes with a manual page. Here is my current version of read along with a couple of functions that it relies on: # A real read function, as in 'read var var var'. Returns failure # on EOF. relies on the 'line' program. nl=' ' fn read { _v=() _i=() { _v=`` $nl {line; echo $status} if (! ~ $_v(2) 0) return $_v(2); _v=`{echo $_v(1)} for (_i in $*) { $_i=$_v(1); sshift _v 1 } $_i=($$_i $_v) }; return 0; } # 'supershift' function for rc. # usage: # sshift varname # sshift varname number # shifts the list varname by number (default 1) positions. fn sshift { if (~ $#* 1 ) { _sshift $1 1 $$1 } else { _sshift $1 $2 $$1 } } # this function does most of the work. # _sshift NAME COUNT LISTELEMS # shift LISTELEMS COUNT items left, and assign the result to NAME. fn _sshift { _vn=() { _vn=$1; shift; shift $1; shift; $_vn=$* } } - cks