Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture stdout and stderr into different variables

Is it possible to store or capture stdout and stderr in different variables, without using a temp file? Right now I do this to get stdout in out and stderr in err when running some_command, but I'd like to avoid the temp file.

error_file=$(mktemp) out=$(some_command 2>$error_file) err=$(< $error_file) rm $error_file 
like image 522
ntc2 Avatar asked Jun 14 '12 06:06

ntc2


1 Answers

Ok, it got a bit ugly, but here is a solution:

unset t_std t_err eval "$( (echo std; echo err >&2) \         2> >(readarray -t t_err; typeset -p t_err) \          > >(readarray -t t_std; typeset -p t_std) )" 

where (echo std; echo err >&2) needs to be replaced by the actual command. Output of stdout is saved into the array $t_std line by line omitting the newlines (the -t) and stderr into $t_err.

If you don't like arrays you can do

unset t_std t_err eval "$( (echo std; echo err >&2 ) \         2> >(t_err=$(cat); typeset -p t_err) \          > >(t_std=$(cat); typeset -p t_std) )" 

which pretty much mimics the behavior of var=$(cmd) except for the value of $? which takes us to the last modification:

unset t_std t_err t_ret eval "$( (echo std; echo err >&2; exit 2 ) \         2> >(t_err=$(cat); typeset -p t_err) \          > >(t_std=$(cat); typeset -p t_std); t_ret=$?; typeset -p t_ret )" 

Here $? is preserved into $t_ret

Tested on Debian wheezy using GNU bash, Version 4.2.37(1)-release (i486-pc-linux-gnu).

like image 141
TheConstructor Avatar answered Oct 31 '22 12:10

TheConstructor