2016-06-16 7 views
3

私はこのコードで間違って何をやっている知ってほしい:SHでlinux:構文エラー:単語予期しない

Syntax error: word unexpected (expecting "in")

しかし、中:私は、次のエラーメッセージが表示されますsh経由

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

実行caseコマンド私はinという単語を持っています。

誰でもこのバグを修正する方法を知っていますか?

ありがとうございます!

+0

'$ 1 'の値は何ですか? –

+0

$ 1が最初のコマンドライン引数です –

+0

私はこれが何であるか知っています。私は '$ 1'の* value *を知りたいと思います。 –

答えて

6

は、あなたのコードは、あなたが、しかし、二重引用符ではないと潜在的に望ましくない副作用について警告を与えれる(shellcheck.netで確認することができます構文的に有効なPOSIXのようなシェルコード、であるあなたの(例えばecho "$PID_PATH_NAME"ではなくecho $PID_PATH_NAMEcase[1]$1には適用されません。

同様に、あなたの質問のコードをコピーして新しいファイルに貼り付け、Ubuntu上でsh(これはDash)を使って実行するとうまくいきます。

このように - あなたのshは、それがどうあるべきかではない場合を除き - 私はあなたのシェルファイルに「奇妙な」の文字を持っていると思われる、このよう通常の空白のようて見える場合も、標準のASCIIの範囲外のUnicode空白としてしかし、そうではありません。 Unicodeノーブレークスペース文字(U_00A0、UTF8は0xC2 0xA0としてエンコードされています)が例です。次のコマンドを実行し、そのような文字を探してくださいするには

script、スクリプトを表す):

LC_ALL=C cat -e script 

と出力のM-^<letter>シーケンスを探し、例えば、前述のノーブレークスペースはM-BM-と表示されます。


[1] case書に与えられたダブルクォートは悪くはないが、必要はありません。

引用符で囲まれていないパラメータ/変数の参照は、ワード分割され、パス名がで最も大きく、POSIXのようなシェルではとなります。caseは興味深い例外です。

以下は、このことを実証し、すべての主要なPOSIXのようなシェル(dashbashkshzsh)で動作します:

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

リテラル引数foo *$1引用符で囲まれていないであっても、case枝にマッチします。
$1の値は、単語分割とパス名展開(グロブ)の両方の対象となる典型的な状況(例えば、echo $1)、とは対照的。)

0

quoting the argumentを試しましたか?ここに掲載したよう

case "$1" in 
... 
+1

これは文字列へのキャストとは呼ばれません。これは引用と呼ばれます。しかし、このCANは実際には整数型変数の文字列への変換として機能します。しかし、case文はそれを文字列として解釈します。とにかく、これはおそらくスクリプトの問題かもしれません。説明については私のコメントを参照してください。 – anishsane

+0

同じエラーが発生しました... –

+1

文字列分割やグロブ展開が起こりにくい 'case'文のその位置に引用符を付ける必要はありません。 –

関連する問題