bash SH linux:语法错误:单词意外

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37862365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:47:00  来源:igfitidea点击:

SH linux: Syntax error: word unexpected

linuxbashubuntuubuntu-14.04sh

提问by pedro.olimpio

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  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 shI get the following error message:

通过执行sh我收到以下错误消息:

Syntax error: word unexpected (expecting "in")

语法错误:单词意外(期望“in”)

But in the casecommand I've the inword.

但是在case命令中我有这个in词。

Anyone know how to fix this bug?

有谁知道如何修复这个错误?

Thanks a lot!

非常感谢!

回答by mklement0

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_NAMErather than echo "$PID_PATH_NAME"), which however does NOT apply to $1in the casestatement[1]).

正如此处发布的那样,您的代码是语法上有效的类似 POSIX 的 shell 代码,您可以在shellcheck.net 上对其进行验证(但是,由于没有双引号您的变量引用(例如,echo $PID_PATH_NAME而不是echo "$PID_PATH_NAME"),然而这并不适用于$1case声明中[1] )。

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

同样,复制问题中的代码并将其粘贴到一个新文件中,然后sh在 Ubuntu(即 Dash)上使用来执行它,也可以正常工作。

Thus - unless your shis 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 looklike normal whitespace, but isn't; the Unicode no-break space character (U_00A0, UTF8-encoded as 0xC2 0xA0) is an example.

因此 - 除非你sh不是它应该的样子 - 我怀疑你的 shell 文件中有“奇怪”的字符,例如标准 ASCII 范围之外的 Unicode 空格,它可能看起来像正常的空格,但不是;Unicode 不间断空格字符(U_00A0, UTF8 编码为0xC2 0xA0)就是一个例子。

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

要查找此类字符,请运行以下命令(其中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-.

并在输出中查找M-^<letter>序列;例如,前面提到的不间断空间显示为M-BM-



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

[1] 用双引号引用case声明中的论点没有坏处,但不是必须的

While unquoted parameter/variable references are word-split and pathname-expanded in mostplaces in POSIX-like shells, caseis a curious exception.

虽然未加引号的参数/变量引用在 POSIX 类 shell中的大多数地方都是分词和路径名扩展的,但这case是一个奇怪的例外。

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

下面演示了这一点,并适用于所有主要的 POSIX 类 shell ( dash, bash, ksh, zsh):

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

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

文字参数foo *匹配case分支,即使$1是不带引号的
(将此与典型情况(例如,echo $1)进行对比,其中 的值$1将受到分词和路径名扩展(通配)的影响。)

回答by Jonathan King

Have you tried quoting the argument?

你有没有试过引用这个论点

case "" in
...