Redirecting Command Output to a Variable in Bash Fails

Redirecting command output to a variable in bash fails

Maybe the output goes to stderr, not stdout? Try this:

OUTPUT=$(sudo apache2ctl configtest 2>&1)

How to store standard error in a variable

It would be neater to capture the error file thus:

ERROR=$(</tmp/Error)

The shell recognizes this and doesn't have to run 'cat' to get the data.

The bigger question is hard. I don't think there's an easy way to do it. You'd have to build the entire pipeline into the sub-shell, eventually sending its final standard output to a file, so that you can redirect the errors to standard output.

ERROR=$( { ./useless.sh | sed s/Output/Useless/ > outfile; } 2>&1 )

Note that the semi-colon is needed (in classic shells - Bourne, Korn - for sure; probably in Bash too). The '{}' does I/O redirection over the enclosed commands. As written, it would capture errors from sed too.

WARNING: Formally untested code - use at own risk.

Redirecting command output to variable as well as console in bash not working

You have an unnecessary redirect on that tee command. Use:

VAR1=$(ps -u "${USER}" | awk 'NR>1 {print $NF}' | tee /proc/$$/fd/1)

They tee works is that it copies its input to its output, and also to any files whose names you give as arguments. The redirection just messages up with its pass-through behavior.

Something else you could do - since we're not talking about some long-running command here - is first set the variable, then print its value:

VAR1=$(ps -u "${USER}" | awk 'NR>1 {print $NF}' )
echo "$VAR1"

... much simpler :-)

Redirecting stdout and stderr to variable within bash script

If you want to redirect for the entirety of your code, instead of using blocks, use the exec command. That is:

stdout_file="/some/path/$1/timestamp.stdout"         # Creating job-id specific folders
stderr_file="/some/path/$1/timestamp.stderr"
exec >"$stdout_file" 2>"$stderr_file"

# ...all code below this point has stdout going to stdout_file, and stderr to stderr_file

How do I redirect output to a variable in shell?

Use the $( ... ) construct:

hash=$(genhash --use-ssl -s $IP -p 443 --url $URL | grep MD5 | grep -c $MD5)

command output not being saved into variable

nginx writes version on stderr, not on stdout.

To capture stderr you can redirect it to stdout:

b=$(nginx -v 2>&1)

storing error message of command output into a shell variable

Just redirect the stdout (normal output) to /dev/null and keep the stderror:

a=$(cp log.txt 2>&1 >/dev/null)

See an example:

$ a=$(cp log.txt 2>&1 >/dev/null)
$ echo "$a"
cp: missing destination file operand after ‘log.txt’
Try 'cp --help' for more information.

The importance to >/dev/null to keep away to normal output that in this case we do not want:

$ ls a b
ls: cannot access a: No such file or directory
b
$ a=$(ls a b 2>&1)
$ echo "$a"
ls: cannot access a: No such file or directory
b
$ a=$(ls a b 2>&1 >/dev/null)
$ echo "$a"
ls: cannot access a: No such file or directory

Note the need of quoting $a when calling it, so that the format is kept. Also, it is better to use $() rather than , as it is easier to nest and also is deprecated.


What does 2>&1 mean?

1 is stdout. 2 is stderr.

Here is one way to remember this construct (altough it is not entirely
accurate): at first, 2>1 may look like a good way to redirect stderr
to stdout. However, it will actually be interpreted as "redirect
stderr to a file named 1". & indicates that what follows is a file
descriptor and not a filename. So the construct becomes: 2>&1.

Redirect STDERR to a variable

You can capture it like this:

error=$(memtester 900 1 2>&1 >/dev/null)

order of redirection operators is important here.

  • 2>&1 - redirects stderr to stdout
  • >/dev/null - redirects stdout to /dev/null


Related Topics



Leave a reply



Submit