I was using a bash script to do some automated testing on a CLI. All of a sudden it does not seem to work. Seems like our devops have done some changes to the OS.

The error i see is

bash-3.2$ sh cli-unit.sh 
cli-unit.sh: line 53: syntax error near unexpected token `('
cli-unit.sh: line 53: ` if ! diff < (echo "$EXPECTED") < (echo "$FOUND") > /dev/null; then'

The code part is

runTest() {
    local TITLE="$1"
    local BODY="$2"
    COUNTER=$((COUNTER + 1))

    local SHELL=$(getShell "$BODY")
    local EXPECTED=$(getOutput "$BODY")
    local FOUND=$(eval "$SHELL")

    if ! diff <(echo "$EXPECTED") <(echo "$FOUND") > /dev/null; then
        echo "--- FAIL: $TITLE"
        diff <(echo "$EXPECTED") <(echo "$FOUND")
        return 1
    PASSED=$((PASSED + 1))
    return 0

Can someone change/correct this for me ? i am unable to rectify it. Thanks in advance.

  • 1
    Whenever you have a shell syntax error, a good first step is to cut and paste your code into shellcheck.net and correct the errors (important) and warnings (might be important) that it identifies. If you have trouble understanding its messages, then come here and ask
    – John1024
    Mar 8, 2018 at 5:17
  • I have done the shellcheck and does not seem to have any error. But when i execute it, i still see the same error.
    – sovenkat
    Mar 8, 2018 at 6:59
  • 1
    @sovenkat It will show errors if you add #!/bin/sh to the top of the shell code fragment in ShellCheck. See my answer.
    – Kusalananda
    Mar 8, 2018 at 7:20

1 Answer 1


Your script is clearly a bash script, but you are running it using sh.

Instead of explicitly using sh to start the script, either

  1. Use bash, or
  2. Make the script executable and add an appropriate #!-line on the first line that points to the bash interpreter, and run the script with ./cli-unit.sh.

The sh shell can not be expected to understand bash-specific shell syntax.

I have a couple of further issues with some of the things in the bit of script that you show:

  • Use lowercase shell variable names so that they don't accidentally clash with the system's environment variables. In the code, you set SHELL, which usually is the path to the current shell interpreter.
  • Don't use diff to do string comparison. Just do if [ "$variable1" != "$variable2" ] to test for inequality.
  • Use printf rather than echo to output variable data (see "Why is printf better than echo?").

Addressing the diff:

if [ "$FOUND" != "$EXPECTED" ]; then
    # code as before
    return 1
# code as before
return 0

Inside the if branch, you may still use diff to show the difference (especially if another script or user is expecting that sort of output from this script). Another option would be to do

if [ "$FOUND" != "$EXPECTED" ]; then
    # $FOUND is different from $EXPECTED
    printf 'FAIL (%s): Found: %s\n' "$TITLE" "$FOUND"
    printf 'FAIL (%s): Expected: %s\n' "$TITLE" "$EXPECTED"
    # other code here
 # rest of script

or something similar.

  • does this look good ? runTest() { local TITLE="$1" local BODY="$2" COUNTER=$((COUNTER + 1)) local SHELL SHELL=$(getShell "$BODY") local EXPECTED EXPECTED=$(getOutput "$BODY") local FOUND FOUND=$(eval "$SHELL") local a="echo $EXPECTED" local b="echo $FOUND" if [ "$a" != "$b" ] > /dev/null then echo "--- FAIL: $TITLE" else [ "$a" = "$b" ] return 1 fi PASSED=$((PASSED + 1)) return 0 }
    – sovenkat
    Mar 8, 2018 at 7:20
  • @sovenkat Just use if [ "$EXPECTED" != "$FOUND" ]; then. There is no need for extra variables to do the test and you don't need to redirect to /dev/null. Inside the if branch, once you have determined that they are different, you may want to use diff to show the difference. There is no need for the else.
    – Kusalananda
    Mar 8, 2018 at 7:22
  • @sovenkat See updated answer.
    – Kusalananda
    Mar 8, 2018 at 7:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.