Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Lonely spacecowboy




----- Original Message ----- From: "Stephane Chazelas" <Stephane_Chazelas@xxxxxxxx>
To: "Brian K. White" <brian@xxxxxxxxx>
Cc: <zsh-users@xxxxxxxxxx>
Sent: Tuesday, March 27, 2007 3:31 PM
Subject: Re: Lonely spacecowboy


On Tue, Mar 27, 2007 at 03:01:42PM -0400, Brian K. White wrote:
You did not say in what way it fails, nor what <cmd> might be.
But I can say 2 things:

1) pipeing into read only "works" in ksh, the real korn ksh not pdksh or
any of the others like bash and zsh that have a "ksh compatibility" mode.
But you can still use a similar construct with file redirection that will
work.
The difference is "|read" creates a child process that read runs in, and
any env variables set in that child process are not visible from the
parent, and the while-do-done command (and all commands in that loop) ar
running in the parent.

While this is true for bash and pdksh it's not true for zsh:

~$ echo foo | read
~$ echo $REPLY
foo

Color me updated.

It doesn't work in one enviroment I use zsh a lot in.

$P$Gecho this is a test |read aa bb cc
$P$Gecho $aa $bb $cc

$P$G


This is latest freestanding (static binary not needing cygwin dll) version of zsh for windows that I have been able to locate, which is quite old,
$P$Gecho $VERSION
3.0.5.001
$P$G

The way cygwin only works by having the cygwin dll installed in the os and can't be delivered in a self-contained package with the file makes cygwin unsuitable for me.


[...]
You might be able to redirect stdin just for the cmd but I never tried that
in a loop like this so I don't know if it actually works.

Generally done as:

while IFS= read -r <&3; do
 cmd ... "$REPLY"
done 3< file.txt

(read without -r or with the default value of IFS is very
special, you generally don't want that in scripts).

Ah of course.


# test for no tty to allow for cron jobs, cgi script, print filter, etc...
tty -s && MYTTY=`tty` || MYTTY=/dev/null
while read
do
     vi "$REPLY" <$MYTTY
done < files.txt

Even if there's a tty, there's no guarantee that stdin is
guaranteed. There's no need for that trick except if you're
using csh type shells that hardly have any fd handling
capability.


You could also just use awk and not worry about stdin and tty and read
etc...
no redirection or piping, no read command, no tty issues, etc...

awk '{system("somecommand \""$0"\"")}' files.txt

Then you'd run into more problems (possibly serious) if the
lines in files.txt contain any ", \, $, `...

Well I quoted the string, we do already know it contains spaces.
I suppose it wouldn't be that much harder to get it single-quoted instead of double-quoted and then it's just up to command to continue handling the string safely. Or you could add as much sanity checking to the awk script as seems necessary.

But I forgot all about xargs, that was nicer than this anyways.

It's a little less efficient because system() spawns a new sh process to
run command in, where the while-read loop will run command right in the
same top level shell process where the while loop itself is running.
[...]

If "<cmd>" is not builtin, there's be as many processes (unless
is not optimised to exec the last command is run). The
difference is on the loading and initialising of sh.

--
Stéphane

Nice. Thanks for all the pointers. I appreciate it.

Brian K. White    brian@xxxxxxxxx    http://www.myspace.com/KEYofR
+++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++.
filePro  BBx    Linux  SCO  FreeBSD    #callahans  Satriani  Filk!



Messages sorted by: Reverse Date, Date, Thread, Author