This question is similar to the following link, but focused on using the command line (bash shell).

Using a simple example, when doing the following command:

$ cat <(date); echo $?
Fri Jul  7 21:04:38 UTC 2017

The exit value is 0 as expected.

In the following command there is an error introduced on purpose, but the return value is still 0:

$ cat <(datE); echo $?
bash: datE: command not found...
Similar command is: 'date'

Is there a way to catch that there was an error in the process substitution when run on the command line (i.e. without having to put it into a script) ?

The solution in the included link above kills the script that is running the command.

  • 1
    Not sure if this fits your definition of "detect an error" but cat <(datE || echo $? >&2) ?? – B Layer Jul 8 '17 at 1:07
  • @BlairM. Thanks, that is a good idea and helps. I was thinking more along the lines of how the cat command would exit with a non-zero value. I was using the linux parallel 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 8 '17 at 1:20
  • Cool. I'll add as an answer then. – B Layer Jul 8 '17 at 1:21
  • The answer I am looking for should address the propagation of the error though. The above suggestion doesn't address that in its current form. – steveb Jul 8 '17 at 1:23
  • Hehe. Okay. I'll think about a more elaborate approach. – B Layer Jul 8 '17 at 1:24

An alternative to using process substitution is to use /dev/stdin as the file arg so that pipes work as expected:

set -o pipefail
datE | cat /dev/stdin

The above example is a bit contrived since cat will read from stdin if not given a file arg. It's useful when a command must be given a file.


In your example:

cat <(datE); echo $?

What happens is that datE throws the error and generates no output. It then throws an error code. However, the (null) input is then presented to cat which happily chews on nothing, and now your exit code is zero.

If you take out the intermediary step, it works as you expect:

$ datE; echo $?
datE: command not found

If you want bash to to abort on any failures in a pipeline and any uncaught error, run the following two commands:

set -e
set -o pipefail

Other shells may provide similar settings.

  • I do understand that removing the cat from the command line will then cause the error to be caught ($? is 127). My example is simple to keep the question clear. Using set -e and set -o pipefail with the cat... version won't cause $? to be 127. This problem came up when using gnu parallel to run commands in a file, some of which use process substitution. – steveb Jul 9 '17 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.