On Sun, 14 Jan 2007, Nadav Har'El wrote:

        : | cat

Try |cat or ;|cat . ':' has the explicit meaning of empty (nop) command. Note that assignments are NOT listed under Commands in the shell manual, as opposed to let and set which are (and with good reason, since they can generate stdout). An assignment used alone at the head of a pipeline is a bug that stems from the misinterpretation by the implementors of the description of a simple command, which is:

'A simple command is a sequence of optional variable assignments fol- lowed by blank-separated words and redirections, and terminated by a control operator.'

The spec is ambiguous enough that the optional variable assignments can be taken as sufficient for an 'empty' command. In fact there already is such a command, it is called ':'. So 'a=3:|cat' is valid for sure but 'a=3|cat' isn't (or should not be).

A 'meaningless' construct in a well-defined language is an error. An
unrecognized error is called a bug.

The examples people showed here are not "meaningless" - they have meaning -
just not a *useful* meaning. In any language you can do things which are

Right, foo=bar is a meaningful construct, but it is used out of context when used like foo=bar|baz. This out of context use is an error. foo=bar is a shell variable assignment, not a command. It should not fork any subprocess and it should not have any output, i.e. it should not manipulate stdout at all. In fact stdout should be closed unless the rhs is in backticks. Worse, 'your' bug is consequent, as it also eats stdin:

  echo "ok"|a=3|cat == ""

Well, the designers of the shells disagreed with you: "a=foo" is a command,
so it can be used in a pipe. The "a=foo cmd .." is a special syntax, which
is irrelevant here (here, a=foo is not followed by a command).

'a=foo cmd' is not a 'special syntax'. It is standard. Using an assignment in a pipe alone, without a command, isn't standard. This is exactly your 'special syntax' turned around: the optional assignment is there but the command isn't. It's always new users who find strange bugs because they use the system in nonstandard ways ;-)

This is not about hair-splitting. An assignment is not a command, it is an assignment. It is up to the implementors to decide whether using an assignment in a pipe stage is an error that should be caught or left to hair-splitting by iglu. Because the lhs of the assignment 'consumes' any stdout output of the rhs the assignment will have no output on stdout. Also the stdin of an assignment is meaningless. This is obvious. Thus allowing the use of an assignment in a pipe is imho a bug. Or more exactly, a failure to limit pipe members to 'generators'. a=3|baz is always equivalent to: a=3;cat </dev/null|baz excepting when the assignment fails, but then it should be written:

  a=3 && </dev/null baz

or, if one wants to be tricky:

  a=3:|baz

which, unlike a=3|baz, might not earn the user any points in a shell script obfuscation competition, and might even work if and when this BUG will be fixed in bash.

Peter

=================================================================
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]

Reply via email to