【问题标题】:SH linux: Syntax error: word unexpectedSH linux:语法错误:单词意外
【发布时间】:2016-10-18 03:47:49
【问题描述】:

我想知道我在这段代码中做错了什么:

#!/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 

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

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

但是在case 命令中我有in 字。

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

非常感谢!

【问题讨论】:

  • $1 的值是多少?
  • $1 是第一个命令行参数
  • 如果你减少到this,这会给出错误吗?
  • 在未来,顺便说一句,尽量遵守stackoverflow.com/help/mcve 的指导方针——代码示例应该最少,包含能够重现相同内容的最少代码量问题,并且 verifiable - 意味着您应该将其复制并粘贴回您的问题中,尝试运行它,并确保这仍然会导致错误(它会捕获隐藏字符之类的东西) .
  • ...另外,理想情况下,shellcheck.net 发现的错误应该在此处提出问题之前修复。

标签: linux bash ubuntu ubuntu-14.04 sh


【解决方案1】:

你试过quoting the argument吗?

case "$1" in
...

【讨论】:

  • 这不称为转换为字符串。这称为引用。虽然,这个 CAN 实际上用作转换为字符串,用于整数变量。但是 case 语句无论如何都会将其解释为字符串。无论如何,这可能是脚本中的问题。请参阅我的评论以获取解释。
  • case 语句中的那个位置不需要引用——不容易出现字符串拆分或全局扩展。
【解决方案2】:

正如此处发布的那样,您的代码在语法上是有效的类似 POSIX 的 shell 代码,您可以在 shellcheck.net 进行验证(但是,由于不加倍,它会警告您可能不需要的副作用- 引用您的变量引用(例如,echo $PID_PATH_NAME 而不是 echo "$PID_PATH_NAME"),但这不适用于 case 语句中的 $1[1] )。

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

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

要查找此类字符,请运行以下命令(script 代表您的脚本):

LC_ALL=C cat -e script

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


[1] 双引号引用case 语句的参数并没有什么坏处,但没有必要

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

以下演示了这一点,并适用于所有主要的类似 POSIX 的 shell(dashbashkshzsh):

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

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

【讨论】:

    猜你喜欢
    • 2016-05-30
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多