How to get the output of a bash command in a variable

I have performed some of these questions (for example, How to set a variable at the output of a command in Bash? ), However, the accepted answers seem to be inoperative for me. I was not sure if I should cancel another question or post my own duplicate, so I apologize if I am wrong here.

I want to get the status of the output and output from several commands in the script that I am collecting. Here is an example of what I used:

cmd_output=$(rm $file) exit_status=$? if [ "${exit_status}" -eq 0 ] then log "Successfully removed the original" ${TAB_LEVEL} else fail "Failed to remove the original, the output was: \n ${cmd_output}" fi 

Log and Failure Features:

 # Usage: fail "Failure message" function fail { echo "FATAL ERROR: $1" >> "${LOG_DIR}/${LOG_FILE}" exit 1 } # Usage: log "Log message" 3 Where the tab-level is 3. function log { if (("${2}" > 0)) then eval "printf ' %.0s' {1..$2}" >> "${LOG_DIR}/${LOG_FILE}" fi echo "$1" >> "${LOG_DIR}/${LOG_FILE}" return 0 } 

In the above example, I use the $ (cmd) format, but I also tried using backlinks.

In my log file, everything that I see when a crash occurs:

FATAL ERROR: Failed to delete the original, the output was: \ n

In addition, the output of unsuccessful commands ends on the screen, as usual. Is there a general reason why my cmd_output variables remain empty?

+8
command-line bash shell ubuntu
source share
3 answers

You must enable the output of the output of special standard errors:

 cmd_output=$(rm "$file" 2>&1) 

Each program has three default streams: these are numbered file descriptors:

 0. Standard input (where the program normally reads from) 1. Standard output (where the program normally writes to) 2. Standard error (where the program normally writes error messages) 

So, to fix the error messages, we have to redirect the standard error output (stderr) to the standard standard output (stdout), which will then be captured by the expression $(...) .

The redirection syntax is implemented using the > "operator. Directly before that, you specify which file descriptor is redirected (default is 1, that is, stdout). And you can specify it to redirect to the file. If after that you write ampersand ( & ), you make it redirect to another file descriptor, so in this example we redirect file descriptor 2 (stderr) to file descriptor 1 (stdout).

Alternatively, you can also redirect input using < "operator", but in this case, the file descriptor defaults to 0 (stdin).

Another observation is that it is probably good practice to place the $file variable between double quotes if it has spaces.

Hope this helps a bit =)

+23
source share

* The nix command usually has two forms of output: standard output ( stdout ) and standard error ( stderr ).

FOO=$(...) captures only stdout and leaves stderr unhindered.

If you want the contents of stderr with this syntax, you need to send a postfix command using 2>&1 so that stderr combined with stdout . (e.g. like this: rm $file 2>&1 )

+5
source share

Since your fail function just exits, that would be much simpler:

 set -e # Abort on failure exec 2>> "${LOG_DIR}/${LOG_FILE}" # Append all errors to LOG_FILE if cmd_output=$(rm $file) log "Successfully removed the original" ${TAB_LEVEL} fi 

The only difference between this and the source code is that it does not print the text FATAL ERROR: Since brevity is a virtue, it is probably best to skip the log function. Report errors loudly succeed quietly.

0
source share

All Articles