Reputation: 1
For this question I will use grep
, because its usage text prints to stderr:
$ grep
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
You can capture stdout easily with process substitution:
$ read b < <(echo hello world)
However stderr slips past the process substitution and prints to the console:
$ read b < <(grep)
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
I would like to capture stderr using process substitution. I am using this now:
$ grep 2> log.txt
$ read b < log.txt
but I am hoping to avoid the temp file.
Upvotes: 11
Views: 4399
Reputation: 9983
A more general solution for a whole subshell is to use exec
to redirect its standard error.
If, instead of the OP's example based on grep
being a single command, you had a sequence of commands in the subshell then you can redirect the standard error of the whole subshell like this:
b=$(cat <(
exec 2>&1
echo "standard output"
echo "standard error" 1>&2
))
echo $b
which puts the output of standard output and standard error into the variable $b
:
standard output standard error
The echo
statements are just examples to output something to each of standard output and standard error.
Upvotes: 1
Reputation: 221
$ grep 2> >(sed 's/e/E/g';)
You can capture grep's stdout and pipe it to sed but, I don't know why (nor how to avoid it) it needs an extra INTRO to return control and display the prompt.
Edit: You can fix that mismatch like this:
$ grep 2> >(sed 's/e/E/g';); sync
Upvotes: 2
Reputation: 8272
Redirect the stderr of your command to stdout:
$ read "b" < <(grep 2>&1)
$ echo "$b"
Usage: grep [OPTION]... PATTERN [FILE]...
Though the conventional way to save the output of a command to a variable in Bash is by using $()
:
$ b=$(grep 2>&1)
$ echo "$b"
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
Upvotes: 17