Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SH linux: Syntax error: word unexpected

I want know what am I doing wrong in this code:

#!/bin/sh
SERVICE_NAME=neocloud
PATH_TO_JAR=/etc/neocloud/cloud.jar
PID_PATH_NAME=/tmp/neocloud-pid
case $1 in
    start)
        echo "Starting $SERVICE_NAME ..."
        if [ ! -f $PID_PATH_NAME ]; then
            nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
                        echo $! > $PID_PATH_NAME
            echo "$SERVICE_NAME started ..."
        else
            echo "$SERVICE_NAME is already running ..."
        fi
    ;;
    stop)
        if [ -f $PID_PATH_NAME ]; then
            PID=$(cat $PID_PATH_NAME);
            echo "$SERVICE_NAME stoping ..."
            kill $PID;
            echo "$SERVICE_NAME stopped ..."
            rm $PID_PATH_NAME
        else
            echo "$SERVICE_NAME is not running ..."
        fi
    ;;
    restart)
        if [ -f $PID_PATH_NAME ]; then
            PID=$(cat $PID_PATH_NAME);
            echo "$SERVICE_NAME stopping ...";
            kill $PID;
            echo "$SERVICE_NAME stopped ...";
            rm $PID_PATH_NAME
            echo "$SERVICE_NAME starting ..."
            nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
                        echo $! > $PID_PATH_NAME
            echo "$SERVICE_NAME started ..."
        else
            echo "$SERVICE_NAME is not running ..."
        fi
    ;;
esac 

executing via sh I get the following error message:

Syntax error: word unexpected (expecting "in")

But in the case command I've the in word.

Anyone know how to fix this bug?

Thanks a lot!

like image 602
pedro.olimpio Avatar asked Jan 05 '23 21:01

pedro.olimpio


1 Answers

As posted here, your code is syntactically valid POSIX-like shell code, which you can verify at shellcheck.net (which will, however, warn you about potentially unwanted side effects due to not double-quoting your variable references (e.g., echo $PID_PATH_NAME rather than echo "$PID_PATH_NAME"), which however does NOT apply to $1 in the case statement[1] ).

Similarly, copying the code in your question and pasting it into a new file and using sh on Ubuntu (which is Dash) to execute it, works fine too.

Thus - unless your sh is not what it should be - I suspect that you have "weird" characters in your shell file, such as Unicode whitespace outside the standard ASCII range, which may look like normal whitespace, but isn't; the Unicode no-break space character (U_00A0, UTF8-encoded as 0xC2 0xA0) is an example.

To look for such characters, run the following (where script represents your script):

LC_ALL=C cat -e script

and look for M- and ^<letter> sequences in the output; for instance, the aforementioned no-break space shows up as M-BM-.


[1] Double-quoting the argument given to the case statement doesn't hurt, but is not necessary.

While unquoted parameter/variable references are word-split and pathname-expanded in most places in POSIX-like shells, case is a curious exception.

The following demonstrates this, and works with all major POSIX-like shells (dash, bash, ksh, zsh):

$ sh -c 'case $1 in "foo *") echo "match";; *) echo "nomatch"; esac' - 'foo *'
match

Literal argument foo * matches the case branch, even though $1 is unquoted.
(Contrast this with the typical situation (e.g., echo $1), where the value of $1 would be subject to both word-splitting and pathname expansion (globbing).)

like image 135
mklement0 Avatar answered Jan 08 '23 12:01

mklement0