Zsh Mailing List Archive
Messages sorted by:
Re: set -F kills read -t
On Mar 19, 6:46pm, Ray Andrews wrote:
} Ok Bart, how would you write it? The above is a bridgehead in as much
} as it accepts input from either end
Command line arguments are a fundamentally different kind of "input".
Files, pipes, and terminals are often called "I/O streams" because
data flows from or to them like water (same analogy from which "pipes"
is derived). Command line arguments are fixed locations in memory
(the argv array in C programs) that may be populated at the time
the program starts; nothing "flows" in the arguments.
So it's better not to think of this as "input from either end." They
are entirely distinct. Because the command line arguments are fixed
at program start, they're often used to control the behavior. Using
the example of "grep" (and temporarily ignoring option flags), the
first argument is the pattern to look for, and *if* there is a second
(and so on) argument, it's the name of the file to look in, so grep
opens that file. Otherwise it uses stdin, but either way it has an
I/O stream in which to look for the pattern. The arguments were only
used to control the choice of stream.
Grep would be much less useful if treated command line arguments as if
they were file *contents* instead of file *names*. That's not to say
one never treats a command line argument as content, but it's not the
} but how could it be improved? I tried 'cat' with no luck.
I'm still not sure I understand exactly what you want to do, but let's
look at a fragment of "man cat" as an example:
cat [OPTION] [FILE]...
Concatenate FILE(s), or standard input, to standard output.
With no FILE, or when FILE is -, read standard input.
(This manpage uses FILE as both the name of the file and as shorthand
for "the contents of FILE", which is common.)
Note that "cat" can actually read standard input MORE THAN ONCE! It
tries again every time it finds "-" as a file name. Most of the time
you'll just get end of file after the first try, but some special
kinds of streams (which includes terminals) can be closed and then
opened again "where they left off" (so to speak).
The equivalent documentation for your "y" function with [[ ! -t 0 ]]
If the input is not a terminal, copy one LINE from standard
input, otherwise LINE is empty.
Concatenate LINE and STRING(s), to standard output.
If that's how you meant for it to work, I can't improve on what you
have, except for some cosmetics (for example, you should not test
[ -n "$1" ] because it's possible for $1 to be empty and $2 to have
something in it).
If you want to copy the entire standard input and then append the
STRING(s) at the end of it, it should be fine to do:
function y ()
if [ ! -t 0 ]; then cat
else echo '(nothing in the pipe)'; fi
if [ $# -gt 0 ]; then print -r -- "$*"
else echo '(nothing in the args)'; fi
Not *exactly* as before since I've assumed that if you'd be copying
multiple lines from the input then it's OK to put a newline after the
'(nothing in the pipe)' string. The "print -r --" is more cosmetics,
so that "y -n" will output the -n instead of suppressing the newline
from echo. If you meant for "y" to accept the options of echo, by
all means change that back.
} I've already done some chains of pipes (using binaries) up to maybe
} half a dozen steps, and you just don't have to worry about time-outs,
} or single lines or anything at all, it just works, even on Tuesday.
Yes, but have you noticed that if you just type at the command line
(or pretty much anything else in your chain of pipes) that it will just
sit there forever waiting for something? It's reading the terminal,
because that's what the shell tells it is the standard input. That's
what all those programs that "just work" doing: an unconditional,
blocking-forever, read from somewhere, stdin by default.
As soon as you throw in the bit about not waiting on the terminal when
there is no pipe on the left, you have to start worrying about a lot
of the stuff that you didn't worry about before.
Messages sorted by: