[TUHS] sh: cmd | >file

markus schnalke meillo at marmaro.de
Fri Jan 3 22:45:53 AEST 2020


Hoi,

in a computer forum I came across a very long command line,
including `xargs' and `sh -c'. Anyways, throughout the thread
it was modified several times, when accidently a pipe symbol
appeared between the command and the output redirection. The
command line did nothing; it ran successful. I was confused,
because I expected to see a syntax error in case of
``cmd|>file''. This made me wonder ...


With help of Sven Mascheck, I was able to clear my understanding.
The POSIX shell grammer provided the answer:

pipeline         :      pipe_sequence 
                 ... 
 
pipe_sequence    :                             command 
                 | pipe_sequence '|' linebreak command 
                 ; 
command          : simple_command 
                 ... 
 
simple_command   : cmd_prefix cmd_word cmd_suffix 
                 | cmd_prefix cmd_word 
                 | cmd_prefix   <--- HIER! 
                 | cmd_name cmd_suffix 
                 | cmd_name 
                 ; 
 
cmd_prefix       :            io_redirect 
                 ... 
 
io_redirect      :           io_file 
                 ... 
 
io_file          : '<'       filename 
                 | LESSAND   filename 
                 | '>'       filename 
                 ... 
 
A redirection is a (full) simple_command ... and because
``simple_command | simple_command'' is allowed, so is
``io_file | io_file''. This can lead to such strange (but
valid) command lines like:
 
	<a | >b 
	>b | <a 
 
Sven liked this one:

	:|>: 

Here some further fun variants:
 
	:|:>: 

	<:|:>: 

They would provide nice puzzles. ;-)


My understanding was helped most by detaching from the
semantics and focussing on syntax. This one is obviously
valid, no matter it has no effect:
 
	:|:|: 

From there it was easier to grasp:
 
	>a | >a | >a 
 
Which is valid, because ``>a'' is a (complete) simple_command.
 
Thus, no bug but consistent grammer. ;-) 


If one would have liked to forbid such a corner case,
additional special case handling would have been necessary
... which is in contrast to the Unix way.
 

Sven checked the syntax against various shells with these
results:

- Syntax ok in these shells:

SVR2 sh (Ultrix), SVR4 sh (Heirloom)
ksh93
bash-1.05, bash-aktuell
pdksh-5.2.14
ash-0.4.26, dash-0.5.6.1
posh-0.3.7, posh-0.12.3
mksh-R24, mksh-R52b
yash-2.29
zsh-3.0.8, zsh-4.3.17

- Exception to the rule:

7thEd sh:

    # pwd|>>file
    # echo $?
    141

On first sight ok, but with a silent error ... SIGPIPE (128+13).


I'd be interested in any stories and information around this
topic.

What about 7thEd sh?


meillo


More information about the TUHS mailing list