I want to write a Bash script in which there are two .sh
files:
main.sh
- main script, in which I call the subscript subscripts/checksum.sh
and write its result to the variable called checksum
subscripts/checksum.sh
- script that returns the output of diff
command comparing contents of two text files (they differs, so in my example diff
command will always return non-zero exit code with some description)$ tree .
.
├── main.sh
└── subscripts
├── checksum.sh
├── file1.sha512sum.txt
├── file1.txt
├── file2.sha512sum.txt
└── file2.txt
2 directories, 6 files
main.sh
:#!/bin/bash
set -e
echo "*** Before checksum"
checksum=$(subscripts/checksum.sh)
echo "*** After checksum"
echo "Checksum value: ${checksum}"
subscripts/checksum.sh
:#/bin/bash
set -e
checksum1=subscripts/file1.sha512sum.txt
checksum2=subscripts/file2.sha512sum.txt
echo "----- Before diff"
if diff_res=$(diff ${checksum1} ${checksum2})
then
echo "Checksums are equal."
else
echo "There is a difference between the checksums."
fi
echo "----- After diff"
echo ${diff_res}
Executing main.sh
gives me below result:
*** Before checksum
*** After checksum
Checksum value: ----- Before diff
There is a difference between the checksums.
1c1 < a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt --- > 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
----- After diff
1c1 < a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt --- > 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
It seems that every command in main.sh
has been ran first and after that the commands from subscripts/checksum.sh
. Why is that and how can I get the correct result (described below)?
By correct result I mean printing *** Before checksum
, then getting into subscripts/checksum.sh
and executing all of its command from first to the last one with printing all three echo
commands to the console and after that assigning the value of diff_res
to checksum
in main.sh
. The whole action should be ended with the last print which is *** After checksum
. In my example the checksum
variable should have value:
1c1
< a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt
---
> 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
*** Before checksum
----- Before diff
There is a difference between the checksums.
----- After diff
*** After checksum
Checksum value: 1c1
< a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt
---
> 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
If I understand correctly, you want to see the before/after lines (ignoring other lines) print in this order:
*** Before checksum
----- Before diff
----- After diff
*** After checksum
But it's actually printing in this order:
*** Before checksum
*** After checksum
----- Before diff
----- After diff
This is because of how you've written main.sh. You wrote this:
checksum=$(subscripts/checksum.sh)
This means that the output of checksum.sh
, including the Before diff
and After diff
lines, won't be printed straight away. It will be stored in a variable to be accessed later.
To put it another way, your code is following these steps:
*** Before checksum
checksum.sh
and store its output (the output has Before diff
and After diff
)*** After checksum
Checksum value:
So that's why lines are displayed in a different order from what you wanted.
If you want checksum.sh
to print Before diff
and After diff
directly to the terminal, without those lines being stored in a variable, you should change checksum.sh
like so:
echo "----- Before diff" >&2
...
echo "----- After diff" >&2
This works because by default, all output goes to stdout which can be stored in variables with $()
. But using >&2
sends the output to stderr, which is displayed in the terminal instead of being stored by $()
.