Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Lonely spacecowboy
- X-seq: zsh-users 11349
- From: "Brian K. White" <brian@xxxxxxxxx>
- To: <zsh-users@xxxxxxxxxx>
- Subject: Re: Lonely spacecowboy
- Date: Tue, 27 Mar 2007 15:01:42 -0400
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- Organization: Aljex Software
- References: <20070327175336.GA22601@solfire>
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.
The fix is to use "while read ... do ...done < file.txt" instead of "|read"
Also you don't really need to specify a variable for read in this case as
there is a built in defaut of $REPLY
while read
do
ls -l "$REPLY"
done < files.txt
2) This whole loop only works if NONE of the programs in the loop reads
stdin!
The above example using "ls" will work.
Be very careful that your <cmd> does not read stdin, nor any child process
it may spawn.
Any interactive program is not useable here unless it can be told somehow to
operate in a non-interactive mode that ignores stdin.
Now that I've said it, maybe you can imagine why given that hint to strart
from.
If cmd reads stdin, well, the whole time the loop is running, including
while <cmd> is running, it's stdin is attached to "<file.txt", which is
waiting, trying, that whole time to write more lines from the file.
So what happens is you get one successful read command, then some number of
bytes or lines gets fed into <cmd>, and the next iteration of read will
never get that data.
Maybe even the whole rest of the file gets eaten by the first iteration of
<cmd> and so you never even get a 2nd iteration of read or the rest of the
loop.
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.
# 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
or you can just hard code it to always use </dev/null if it never actually
needs to be interactive.
while read
do
somecommand "$REPLY" </dev/null
done < files.txt
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
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.
Brian K. White brian@xxxxxxxxx http://www.myspace.com/KEYofR
+++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++.
filePro BBx Linux SCO FreeBSD #callahans Satriani Filk!
----- Original Message -----
From: <meino.cramer@xxxxxx>
To: <zsh-users@xxxxxxxxxx>
Sent: Tuesday, March 27, 2007 1:53 PM
Subject: Lonely spacecowboy
Hi,
I _always_ fail with constructions like
cat file.txt | while read file
do
<cmd> "${file}"
done
when file.txt containing one file per line and
a filename looks like:
This is an odd filename.txt
. Is there one for all cure for such a constellation?
Too much space gives me headaches ! ;)
Thank you very much for any help in advance! :)
Keep zshing!
mcc
--
Please don't send me any Word- or Powerpoint-Attachments
unless it's absolutely neccessary. - Send simply Text.
See http://www.gnu.org/philosophy/no-word-attachments.html
In a world without fences and walls nobody needs gates and windows.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author