How to save output from command (eg. diff) into a variable
This works:
if diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/null; then echo "Passed $x"; else echo "Failed $x"; fi
If you use a variable instead of echo
you could drop the else
branche: set the variable to false before the if
and save 2 lines of code.
If you want to actually put the result into a variable use:
some_var="$(diff "./helloworld$x.out" "./output/helloworld$x.out")"
Including my test to see if it does actually work:
rinzwind@discworld:~$ touch 1 rinzwind@discworld:~$ touch 2 rinzwind@discworld:~$ more test if diff 1 2 >/dev/null; then echo "Passed $x"; else echo "Failed $x"; fi rinzwind@discworld:~$ ./test Passed rinzwind@discworld:~$ vi 2 rinzwind@discworld:~$ more 2 2 rinzwind@discworld:~$ ./test Failed
On the >/dev/null
part: >/dev/null 2>&1
will send output to >/dev/null
and 2>&1
will send standard errors to the same file (&1
means 'use first parameter') in front of this command (so it also uses /dev/null
).
sidenote: sdiff
will show a side-by-side diff
listings:
sdiff 1 2 1 1 2 2 3 3 4 4 5 5 7 7 > 8 9 9 10 10
diff
can even suppress output completely except for the "Files /bin/bash and /bin/sh differ" message using the code below.
file1="./helloworld$x.out"
file2="./output/helloworld$x.out"
if diff -q "$file1" "$file2"; then
echo "Passed $x"
else
echo "Failed $x"
fi
If you even want to hide that message, you've to append > /dev/null
after the diff command to hide the output of diff
:
if diff -q "$file1" "$file2" >/dev/null; then
/dev/null
is a special file that acts as a blackhole, if you write to it, it'll be gone, if you're reading from it, you'll get nothing back.
Note that bash does not need ;
to end lines.
As for the original question, to save the output of an program in a variable:
file1="./helloworld$x.out"
file2="./output/helloworld$x.out"
output="$(diff -q "$file1" "$file2")"
# the quotes are mandatory, this checks whether $output is empty or not
if [ -n "$output" ]; then
echo "Passed $x"
else
echo "Failed $x"
fi
Alternative ways to check whether a variable is empty:
[ "$output" = "" ]
[ "$output" == "" ]
[[ "$output" == "" ]]
[[ $output == "" ]]
If you're using Bash, the last two commands are recommended for string comparison. Otherwise, the first and [ -n "$output" ]
is recommended.
a) The output of command1 can be catched with
output=$(diff "helloworld$x.out" "output/helloworld$x.out")
or with backticks, but those are discouraged, because you can't nest them, and they might be hard to distinguish from apostrophs, depending on the font:
output=`cmd1`
b) Instead of writing to a file, and then reading that file, (or grabbing the output, and then echoing it) you would use a pipe directly:
cmd1 > file
cat file | cmd2
output=$(cmd1)
echo "${output}" | cmd2
=>
cmd1 | cmd2
but in your example, you're not interested in the output, but the outcome of the program - did it work?
diff "helloworld$x.out" "output/helloworld$x.out" && echo "success" || echo "failure"
To read about the use of && and || search for "shortcut AND and shortcut OR".
To keep the output clean, you can redirect the output of 'diff' to nowhere:
diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null && echo "success" || echo "failure"
To grab success and evaluate it later, you store the result of the last command in a variable with $?:
diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null
result=$?
# do something else
case $result in
0) echo success ;;
*) echo failure ;;
esac
If you want to know if two files are the same or differ (but don't care what the difference actually is), cmp
is more suitable.
if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi