webentwicklung-frage-antwort-db.com.de

Shell-Skript-Syntaxfehler: Unerwartetes Ende der Datei

Im folgenden Skript bekomme ich einen Fehler: 

syntaxfehler: unerwartetes Ende der Datei

Was ist dieser Fehler, wie kann ich ihn beheben? Es zeigt auf die Zeile, in der die Funktion aufgerufen wird.

#!/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)
28
Rajeev

Bearbeiten: Beachten Sie, dass der ursprüngliche Beitrag seit dem Schreiben dieser Antwort bearbeitet und neu formatiert wurde. Sie sollten sich den Verlauf ansehen, um die ursprüngliche Formatierung zu sehen, um den Kontext für diese Antwort zu verstehen.

Dieser Fehler tritt häufig auf, wenn die Struktur nicht übereinstimmt. Das heißt, Sie haben keine doppelten Anführungszeichen, keine einfachen Anführungszeichen, und Sie haben keine Kontrollstruktur geschlossen, z. B. ein fehlendes fi mit einem if oder ein fehlendes done mit einem for.

Der beste Weg, um diese zu erkennen, ist die korrekte Einrückung, die Ihnen zeigt, wo Sie eine defekte Kontrollstruktur haben, und Syntax-Hervorhebung, die Ihnen zeigt, wo die Anführungszeichen nicht übereinstimmen.

In diesem speziellen Fall kann ich sehen, dass Ihnen ein fi fehlt. Im letzten Teil Ihres Codes haben Sie 5 ifs und 4 fis. Sie haben jedoch auch eine Reihe anderer Probleme: Ihr touch /tmp/alert.txt...-Befehl ist syntaktisch ungültig und Sie benötigen ein Leerzeichen vor der schließenden Klammer eines if-Tests.

Bereinigen Sie Ihren Code und die Fehler fangen an, hervorzuheben.

72
camh

In meinem Fall habe ich festgestellt, dass das Einfügen eines hier eingeblendeten Dokuments (wie sqplus ... << EOF) die gleichen Fehler hervorruft, wie unten gezeigt:

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

Nach dem Entfernen der Einrückung ging es also gut.

Ich hoffe es hilft...

10
Praveen Rao K

Ich hatte dieses Problem beim Ausführen eines Skripts in Cygwin. Behebung durch Ausführen von dos2unix im Skript, wobei die richtige Beschreibung des Problems und der Lösung in dieser Antwort angegeben ist. 

4
shtolik

in meinem Fall war das Problem in der EOL-Konvertierung. (Ende der Linie).

ich habe die Datei unter Windows erstellt und erst nachdem ich die EOL von Windows (CR LF) in Unix (LF) konvertiert hatte, lief alles gut.

Ich habe die Konvertierung mit Notepad ++ sehr leicht von: Edit -> EOL Conversion -> Unix (LF) durchgeführt.

4
David Gidony

Ich habe festgestellt, dass dies manchmal durch Ausführen einer MS-DOS-Version einer Datei verursacht wird. Wenn das der Fall ist, sollte Dos2ux das beheben.

dos2ux file1 > file2
3
patel8786
echo"==================PS COMMAND SNAPSHOT=============================================================="

muss sein

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

Andernfalls wird ein Programm oder ein Befehl mit dem Namen echo"===... gesucht.

weitere probleme:

Wenn Sie einen Grep ausführen (-A1: + 1-Zeilen-Kontext) 

grep -A1 "if " cldtest.sh 

sie finden einige eingebettete Wenns und 4 Wenn/Dann-Blöcke. 

grep "fi " cldtest.sh 

zeigt nur 3 übereinstimmende fi-Anweisungen. Also hast du auch eine Fi vergessen.

Ich stimme mit camh überein, dass die korrekte Einrückung von Anfang an dazu beiträgt, solche Fehler zu vermeiden. Wenn Sie den gewünschten Weg später finden, bedeutet dies doppelte Arbeit in einem solchen Spaghetti-Code.

2
user unknown

Einrückung bei Verwendung eines Blocks kann diesen Fehler verursachen und ist sehr schwer zu finden. 

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

=> Das obige Beispiel führt zu einem Fehler, da EOSQL eingerückt ist. Entfernen Sie die Vertiefung wie unten gezeigt. Dies zu veröffentlichen, weil ich über eine Stunde gebraucht habe, um den Fehler herauszufinden.

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
2
ibaralf

Es hat nichts mit dem Problem des OP zu tun, aber mein Problem war, dass ich ein Noob-Shell-Scripter bin. Alle anderen Sprachen, die ich verwendet habe, erfordern Klammern, um Methoden aufzurufen, während Shell das nicht zu mögen scheint.

function do_something() {
  # do stuff here
}

# bad
do_something()

# works
do_something
1
ps2goat

Sie haben ein nicht geschlossenes Zitat, eine Klammer, eine Klammer, ob, eine Schleife oder etwas anderes.

Wenn Sie es nicht einfach durchsehen können (ich würde einen Syntax-Farbeditor und einen ordentlichen Einrückungsstil empfehlen), nehmen Sie eine Kopie des Skripts und löschen Sie die Hälfte davon. Wenn das Skript so weit wie möglich ausgeführt wird, liegt das Problem in der anderen Hälfte. Wiederholen Sie diesen Vorgang, bis Sie das Problem eingegrenzt haben.

1
ams

Hilfreicher Beitrag, ich habe festgestellt, dass mein Fehler else if anstelle von Elif verwendet wurde,

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

Behebung des Problems:

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

Beim Versuch, eine in Windows OS erstellte Skriptdatei mit Textpad auszuführen, ist der gleiche Fehler aufgetreten. damit kann man das richtige Dateiformat wie Unix/Mac usw. auswählen oder das Skript in Linux selbst erstellen.

0
musthafa

Es kann auch durch Ableiten eines Paares von geschweiften Klammern in einer Leitung verursacht werden.

Das schlägt fehl:

{ /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

während dies erlaubt ist:

{
   /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