This program should demonstrate it. I create a new process and want to redirect both stdout and stderr to the same port, but it does not work. I think run-process could check if a pipe is already associated with the symbol 'abc' and reuse it. Though I guess there may be some hairy details I didn't see.
(print "echo stdout")
(print "echo stderr >&2")))
(sys-chmod "test.sh" #o755)
(let ((p (run-process "./test.sh" :redirects '((> 2 abc) (> 1 abc)))))
(print (port->string (process-output p 'abc))))
I've never thought of this kind of use case, probably because I'm too familiar with shell and I'd write ((> 2 abc) (>& 1 2)) without thinking much. Now that I consider this, I don't think there's a problem to interpret ((> 2 abc) (> 1 abc)) as ((> 2 abc) (>& 1 2)).
((> 2 abc) (>& 1 2))
((> 2 abc) (> 1 abc))
Another option is to prohibit using the same sink more than once. In shell, you generally shouldn't write:
./test.sh 2>abc >abc
because it opens the file abc twice, and writing to stdout and stderr could overwrite each other. If we treat ((> 2 abc) (> 1 abc)) as ((> 2 abc) (>& 1 2)), then probably we should treat ((> 2 "abc") (> 1 "abc")) in the same way, but that breaks the consistency to the shell behavior.
((> 2 "abc") (> 1 "abc"))
Of course we don't need to be precisely consistent with shell (we already have different behavior in the order of processing redirections), but it may be clearer to ask users to use >& to explicitly merge outputs.
gauche.process - Check duplicate symbols as pipe names in redirects
I committed the change that raises an error if pipe names duplicate. I might change my mind if a reasonable use case (that is, >& isn't enough) is found.