0

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
    fi
    PASSED=$((PASSED + 1))
    return 0
}

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

Michael Homer
  • 76,565
  • 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 08 '18 at 05: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 08 '18 at 06: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 08 '18 at 07:20

1 Answers1

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
fi
# 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
 fi
 # rest of script

or something similar.

Kusalananda
  • 333,661
  • 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 08 '18 at 07: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 08 '18 at 07:22
  • @sovenkat See updated answer. – Kusalananda Mar 08 '18 at 07:32