In bash
, process substitutions are started as background jobs. You can get the pid of the leading process of the last one with $!
and you can get its exit status with wait thatpid
like for other background jobs:
$ bash -c 'cat <(exit 3); wait "$!"; echo "$?"'
3
Now, that won't help if you need to use two process substitutions in the same command as in diff <(cmd1) <(cmd2)
.
$ bash -c 'cat <(exit 3) <(exit 4); wait "$!"; echo "$?"'
4
The pid of exit 3
above is lost
It's recoverable with this kind of trick:
unset -v p1 p2
x='!'
cat <(exit 3) ${!x#${p1=$!}} <(exit 4) ${!x#${p2=$!}}
where both pids are stored in $p1
and $p2
, but that's of no use as only the last one is inserted in the shell's job table and wait
will refuse to wait on $p1
wrongly claiming that it is not a child of this shell, even if $p1
has not terminated yet:
$ cat test-script
unset -v p1 p2
x='!'
set -o xtrace
cat <(echo x; exec >&-; sleep 1; exit 3) ${!x#${p1=$!}} <(exit 4) ${!x#${p2=$!}}
ps -fH
wait "$p1"; echo "$?"
wait "$p2"; echo "$?"
$ bash test-script
++ echo x
++ exec
++ sleep 1
+ cat /dev/fd/63 /dev/fd/62
++ exit 4
x
+ ps -fH
UID PID PPID C STIME TTY TIME CMD
chazelas 15393 9820 0 21:44 pts/4 00:00:00 /bin/zsh
chazelas 17769 15393 0 22:19 pts/4 00:00:00 bash test-script
chazelas 17770 17769 0 22:19 pts/4 00:00:00 bash test-script
chazelas 17772 17770 0 22:19 pts/4 00:00:00 sleep 1
chazelas 17776 17769 0 22:19 pts/4 00:00:00 ps -fH
+ wait 17770
test-script: line 6: wait: pid 17770 is not a child of this shell
+ echo 127
127
+ wait 17771
+ echo 4
4
$ ++ exit 3
More on that at @mosvy's answer to Run asynchronous tasks and retrieve their exit code and output in bash
cat <(datE || echo $? >&2)
?? – B Layer Jul 08 '17 at 01:07cat
command would exit with a non-zero value. I was using the linuxparallel
command to run a bunch of commands in a file and want it to return a non-zero value if one using "process substitution" fails. That was a detail not really needed for this question. – steveb Jul 08 '17 at 01:20cat <(datE; echo $?)
– George Vasiliou Jul 08 '17 at 22:28cat
command to exit with a non-zero value. In the case where gnu parallel is used to run a number of commands in a file (at least one using process substitution), it would be helpful to have the command to fail with a non-zero value if the process substitution argument fails with a non-zero value. There are ways to work around this (e.g. put in a bash script), but it would be handy to have the error work its way up. – steveb Jul 10 '17 at 17:24