Search code examples
bashconditional-statementssyntax-errorunexpected-token

Conditional Statement Command Syntax Error in Bash Script


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:

  1. Why did the script fail with a syntax error when trying to interpret the $( diff <(echo $md5hash) <(echo $filehash) within the original conditional statement?

  2. In my updated conditional statements, assuming both hashes are the same, why did if [ "$filehash" = "$md5hash" ] fail but if [[ "$filehash" == "$md5hash" ]] succeed? From my research, it looks like both are valid ways of comparing strings in bash.

Thanks in advance!


Solution

  • 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!