web-dev-qa-db-ja.com

シェルスクリプト構文エラー:予期しないファイルの終わり

次のスクリプトでは、エラーが発生します。

構文エラー:予期しないファイルの終わり

このエラーはどのように再保存できますか?関数が呼び出される行を指しています。

#!/bin/sh

expected_diskusage="264"
expected_dbconn="25"
expected_httpdconn="20"
expected_cpuusage="95"
#expected_fd="100"

httpdconn=`ps -ef|grep -i httpd|grep -v grep|wc -l` #httpd connections
cpu_usage=`ps aux|awk 'NR > 0 { s +=$3 }; END {print s}'`
disk_usage=`df -h|awk {'print $2'}|head -n3|awk 'NF{s=$0}END{print s}'`
#db_connections=`mysql -uroot -pexxxxxx -s -N -e "show processlist"|wc -l`

db_connections=6
cld_alert()
{
    nwconn=$1
    cpu_usage=$2
    disk_usage=$3
    db_connections=$4
    message=$5
    `touch /tmp/alert.txt && > /tmp/alert.txt`
    date=`date`
    echo -e "$date\n" > /tmp/alert.txt
    echo -e "$message" >> /tmp/alert.txt
    path="/proc/$httpd/fd/";
    cd $path
    tfd=`ls -l|wc -l`;
    sfd=`ls -ltr|grep sock|wc -l`;
    echo "Total fds: $tfd" >> /tmp/alert.txt
    echo "Socket fds: $sfd" >> /tmp/alert.txt
    echo "Other fds: $[$tfd - $sfd]" >> /tmp/alert.txt


    freememory=`vmstat | awk '{if (NR == 3) print "Free Memory:"\$4}'`;
    echo "Free memory :$freememory" >> /tmp/alert.txt
    Bufferedmemory=`vmstat | awk '{if (NR == 3) print "Buffered Memory:"\$5}'`;
    echo "Buffered memory $Bufferedmemory" >> /tmp/alert.txt
    CacheMemory=`vmstat | awk '{if (NR == 3) print "Cache Memory:"\$6}'`;
    echo "Cache memory : $CacheMemory" >> /tmp/alert.txt
    sshconn=`netstat -an|grep 22|wc -l`  #ssh connections
    httpsconn=`netstat -an|grep 443|wc -l`  #https connections
    wwwconn=`netstat -an|grep 80|wc -l`  #www connections
    echo "Disk usage is $disk_usage" >> /tmp/alert.txt
    echo "DB connections $db_connections" >> /tmp/alert.txt
    echo "Network connections $nwconn" >> /tmp/alert.txt
    echo "CPU Usage: $cpu_usage" >> /tmp/alert.txt
    topsnapshot=`top -n 1 -b`
    echo "===========================TOP COMMAND    SNAPSHOT====================================================";
    echo "$topsnapshot" >> /tmp/alert.txt
    echo"==================PS COMMAND SNAPSHOT=============================================================="
    entireprocesslist=`ps -ef`
    echo "$entireprocesslist" >> /tmp/alert.txt


    echo Hello hi"";

}



message=""
if [ ${disk_usage%?} -le $expected_diskusage ]    ##{x%?} Removes last character
then
    echo "disk usage exceeded";
    message="Disk usage limit exceeded \nCurrent disk usage is $disk_usage\nConfigured disk usage is    $expected_diskusage\n\n\n\n\n";
    #Checking for CPU usage
    if [ $cpu_usage -ge $expected_cpuusage]    ##{x%?}
    then
        echo "CPU usage exceeded";
        if [ $message -ne "" ]
        then
            message="$message\n\nCPU usage exceeded configured usage limit \nCurrent CPU usage is $cpu_usage\nConfigured CPU usage is $expected_cpuusage\n\n\n\n\n";
        else
            message="CPU usage exceeded configured usage limit \nCurrent CPU usage is   $cpu_usage\nConfigured CPU usage is $expected_cpuusage\n\n\n\n\n";
        fi ;
    fi
    #Checking for httpd connections
    if [ $httpdconn -ge $expected_httpdconn]    ##{x%?}
    then
        echo "HTTPD connections exceeded";
        if [ $message -ne "" ]
        then
            message="$message\n\nHTTPD connections exceeded configured usage limit \nCurrent HTTPD connections is $httpdconn\nConfigured HTTPD connection is $expected_httpdconn";
        else
            message="HTTPD connections exceeded configured usage limit \nCurrent HTTPD connections is $httpdconn\nConfigured HTTPD connection is $expected_httpdconn";
        fi ;
    fi ;
    message="$message\n\n\n\n\n";
    value=$(cld_alert $message $httpdconn $cpu_usage $disk_usage $db_connections)
37
Rajeev

編集:この回答が書かれて再フォーマットされてから、元の投稿が編集されていることに注意してください。この回答のコンテキストを理解するには、履歴を見て元のフォーマットを確認する必要があります。

このエラーは、構造の不一致がある場合によく発生します。つまり、一致する二重引用符がなく、単一引用符に一致せず、fiifであるなどの制御構造を閉じていない場合、またはdoneforが欠落しています。

これらを見つける最良の方法は、正しいインデントを使用することです。これにより、制御構造が壊れている場所が表示され、構文の強調表示により、引用符が一致しない場所が表示されます。

この特定のケースでは、fiが欠落していることがわかります。コードの後半には、5つのifsと4つのfisがあります。ただし、他にも多くの問題があります。逆引用符で囲まれたtouch /tmp/alert.txt...コマンドは構文的に無効であり、ifテストの閉じ括弧の前にスペースが必要です。

コードをクリーンアップすると、エラーが目立ち始めます。

82
camh

私の場合、問題はEOL変換にありました。 (行末)。

私はWindows上でファイルを作成し、EOLをwindows(CR LF)からunix(LF)に変換した後にのみ、すべてがうまくいきました。

Notepad ++を使用した変換は非常に簡単でした。編集-> EOL変換-> Unix(LF)

12
David Gidony

私の場合、インデントされたhere文書(sqplus ... << EOFなど)ステートメントを配置すると、次のように同じエラーが発生することがわかりました。

./dbuser_case.ksh: line 25: syntax error: unexpected end of file

このため、インデントを削除した後、それはうまくいきました。

それが役に立てば幸い...

10
Praveen Rao K

Cygwinでスクリプトを実行すると、この問題が発生しました。スクリプトでdos2unixを実行し、問題と解決策の適切な説明を その答え

4
shtolik

これは、MS DOSバージョンのファイルを実行していることが原因であることがわかっています。その場合、dos2uxで修正する必要があります。

dos2ux file1 > file2
4
patel8786

ブロック使用時のインデントはこのエラーの原因になる可能性があり、見つけるのは非常に困難です。

if [ ! -d /var/lib/mysql/mysql ]; then
   /usr/bin/mysql --protocol=socket --user root << EOSQL
        SET @@SESSION.SQL_LOG_BIN=0;
        CREATE USER 'root'@'%';
   EOSQL
fi

=> EOSQLがインデントされているため、上記の例ではエラーが発生します。以下に示すように、インデントを削除します。エラーを把握するのに1時間以上かかったため、これを投稿しました。

if [ ! -d /var/lib/mysql/mysql ]; then
   /usr/bin/mysql --protocol=socket --user root << EOSQL
        SET @@SESSION.SQL_LOG_BIN=0;
        CREATE USER 'root'@'%';
EOSQL
fi
3
ibaralf
echo"==================PS COMMAND SNAPSHOT=============================================================="

する必要があります

echo "==================PS COMMAND SNAPSHOT=============================================================="

そうでない場合は、echo"===...という名前のプログラムまたはコマンドが検索されます。

その他の問題:

Grepを実行する場合(-A1:+ 1行コンテキスト)

grep -A1 "if " cldtest.sh 

いくつかの埋め込みifと4つのif/thenブロックがあります。

grep "fi " cldtest.sh 

3つの一致するfiステートメントのみが明らかになります。だから、あなたも1つのfiを忘れました。

私はcamhに同意します。最初からの正しいインデントはそのようなエラーを避けるのに役立ちます。後で目的の方法を見つけることは、そのようなスパゲッティコードで二重に作業することを意味します。

2
user unknown

OPの問題とは関係ありませんが、私の問題は、私がnoob Shellスクリプト作成者であることです。私が使用した他のすべての言語では、メソッドを呼び出すために括弧が必要ですが、シェルはそれを好まないようです。

function do_something() {
  # do stuff here
}

# bad
do_something()

# works
do_something
1
ps2goat

閉じていない引用符、中括弧、括弧、if、ループ、または何かがあります。

見ただけでは表示されない場合(構文の色付けエディターときちんとしたインデントスタイルをお勧めします)、スクリプトのコピーを取り、その半分を削除して、有効なはずの場所を切り取ります。スクリプトが可能な限り実行される場合、問題は残りの半分にあります。問題を絞り込むまで繰り返します。

1
ams

参考になった投稿では、私のエラーがElifの代わりにelse ifを使用していることがわかりました。

if [ -z "$VARIABLE1" ]; then
    # do stuff
else if [ -z "$VARIABLE2" ]; then
    # do other stuff
fi

これに変更して修正しました:

if [ -z "$VARIABLE1" ]; then
    # do stuff
Elif [ -z "$VARIABLE2" ]; then
    # do other stuff
fi
0
pinkston00

テキストパッドを使用して、Windows OSで作成されたスクリプトファイルを実行しようとしたときに、同じエラーが発生しました。そのため、unix/macなどの適切なファイル形式を選択したり、Linux自体でスクリプトを再作成したりできます。

0
musthafa

また、ライン上の中括弧のペアから配管することによっても発生する可能性があります。

これは失敗します:

{ /usr/local/bin/mycommand ; outputstatus=$? } >> /var/log/mycommand.log 2>&1h
do_something
#Get NOW that saved output status for the following $? invocation
sh -c "exit $outputstatus"
do_something_more

これは許可されていますが:

{
   /usr/local/bin/mycommand
   outputstatus=$?
} >> /var/log/mycommand.log 2>&1h
do_something
#Get NOW that saved output status for the following $? invocation
sh -c "exit $outputstatus"
do_something_more
0
Envite