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)
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 if
s und 4 fi
s. 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.
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...
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.
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.
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
echo"==================PS COMMAND SNAPSHOT=============================================================="
muss sein
echo "==================PS COMMAND SNAPSHOT=============================================================="
Andernfalls wird ein Programm oder ein Befehl mit dem Namen echo"===...
gesucht.
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.
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
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
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.
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
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.
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