I ran into a command syntax issue for a conditional statement in a script that someone else wrote. The script is as follows (truncated).
#! /bin/bash
# app_upgrade.sh
# Verify file integrity
filehash=$( md5sum install_package.tgz )
md5hash=$( cat install_package.tgz.md5 )
if [ -z $( diff <(echo $md5hash) <(echo $filehash) ) ]; then
printf "File Integrity Check Passed"
else
printf "File Integrity Check Failed"
exit
fi
When I run this script, it fails when trying to interpret the conditional statement due to an unexpected opening parenthesis. The exact error reported to the CLI is as follows.
app_upgrade.sh: command substitution: line 118: syntax error near unexpected token `('
app_upgrade.sh: command substitution: line 118: ` diff <(echo $md5hash) <(echo $filehash) )'
I verified that diff is an executable command on my system by the same user as that running the script. I also ran the diff <(echo $md5hash) <(echo $filehash)
from the CLI and this worked without any issues. I also tried to escape the parentheses but that also failed. I am stumped as to why this is causing an issue.
As a workaround, I tried a few other conditionals since I would not have used diff for the comparison had I been writing the script in the first place. I tried the following replacements for the conditional specified in the script above.
if [ "$filehash" = "$md5hash" ]
However, this did not work. Even though the hashes were the same, the conditional caused the comparison to fail unexpectedly.
if [[ "$filehash" == "$md5hash" ]]
This finally worked.
In summary, my questions are:
Why did the script fail with a syntax error when trying to interpret the
$( diff <(echo $md5hash) <(echo $filehash)
within the original conditional statement?In my updated conditional statements, assuming both hashes are the same, why did
if [ "$filehash" = "$md5hash" ]
fail butif [[ "$filehash" == "$md5hash" ]]
succeed? From my research, it looks like both are valid ways of comparing strings in bash.
Thanks in advance!
CodePudding user response:
When you run your script against shellcheck
linter you can see the error
In ./test.sh line 9: if [ -z $( diff <(echo $md5hash) <(echo $filehash) ) ]; then ^-- SC2046 (warning): Quote this to prevent word splitting. ^------^ SC2086 (info): Double quote to prevent globbing and word splitting. ^-------^ SC2086 (info): Double quote to prevent globbing and word splitting.
You have to quote the if
expression to avoid word splitting:
#! /bin/bash
# app_upgrade.sh
# Verify file integrity
filehash=$( md5sum install_package.tgz )
md5hash=$( cat install_package.tgz.md5 )
# mind the `"` quotation marks around
if [ -z "$( diff <(echo $md5hash) <(echo $filehash) )" ]; then
printf "File Integrity Check Passed"
else
printf "File Integrity Check Failed"
exit
fi
CodePudding user response:
My issue was shell related. The root cause of my issue was a noexec
security constraint in the /home/ directory so I could not run ./app_upgrade.sh
from there. However, sh app_upgrade.sh
worked fine and executed the script, but I was not running it as bash as I intended. Using bash app_upgrade.sh
allowed the script to run properly. So the root cause here was a permissions issue in the directory I was executing the script from causing me to incorrectly execute the bash script with the sh
command.
In summary:
[user@host ~]$ ./app_upgrade.sh
resulted in bash: ./app_upgrade.sh: Permission denied
[user@host ~]$ sh app_upgrade.sh
executed the script but not as bash so this caused an issue interpreting one of the lines of code properly.
[user@host ~]$ bash app_upgrade.sh
executed the script properly without errors.
Had I originally run this in a directory that did not have noexec
constraint then the issue would never have manifested.
Thanks for the all the comments, suggestions and help!