Синтаксическая ошибка сценария оболочки: неожиданный конец файла
В следующем скрипте я получаю ошибку:
синтаксическая ошибка: неожиданный конец файла
Что это за ошибка, как я могу ее исправить? Он указывает на строку, где вызывается функция.
#!/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)
10 ответов
Изменить: Обратите внимание, что оригинальное сообщение было отредактировано с момента написания этого ответа и было переформатировано. Вы должны посмотреть историю, чтобы увидеть оригинальное форматирование, чтобы понять контекст этого ответа.
Эта ошибка часто возникает, когда у вас несоответствующая структура, то есть у вас нет совпадающих двойных кавычек, совпадающих одинарных кавычек, не закрыта управляющая структура, такая как отсутствующая fi
с if
или пропавший done
с for
,
Лучший способ определить это - использовать правильный отступ, который покажет вам, где у вас нарушена структура управления, и подсветку синтаксиса, которая покажет, где кавычки не совпадают.
В этом конкретном случае, я вижу, что вам не хватает fi
, В последней части вашего кода у вас есть 5 if
с и 4 fi
s. Однако у вас также есть ряд других проблем - ваши кавычки touch /tmp/alert.txt...
Команда синтаксически неверна, и вам нужно пробел перед закрывающей скобкой if
тестовое задание.
Очистите свой код, и ошибки начинают выделяться.
В моем случае проблема была в преобразовании EOL. (Конец линии).
Я создал файл в Windows, и только после того, как я преобразовал EOL из Windows(CR LF) в Unix(LF), все прошло хорошо.
Я сделал преобразование с Notepad++ очень легко из: Edit -> EOL Conversion -> Unix (LF)
Не имеет отношения к проблеме ОП, но моя проблема заключалась в том, что я являюсь сценаристом оболочки noob. Все остальные языки, которые я использовал, требуют скобок для вызова методов, тогда как shell, похоже, не такой.
function do_something() {
# do stuff here
}
# bad
do_something()
# works
do_something
В моем случае я обнаружил, что размещение отступов здесь (например, sqplus ... << EOF) операторов также вызывает ту же ошибку, как показано ниже:
./dbuser_case.ksh: line 25: syntax error: unexpected end of file
Так что после удаления отступа для этого все прошло нормально.
Надеюсь, поможет...
Отступ при использовании блока может вызвать эту ошибку, и его очень трудно найти.
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 имеет отступ. Удалите отступы, как показано ниже. Размещая это, потому что мне потребовалось больше часа, чтобы выяснить ошибку.
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
Я обнаружил, что это иногда вызвано запуском версии файла MS Dos. Если это так, то dos2ux должен это исправить.
dos2ux file1 > file2
У меня была эта проблема при запуске какого-то скрипта в cygwin. Исправлено при запуске dos2unix
на сценарии, с надлежащим описанием проблемы и решения, указанного в этом ответе
Полезный пост, я обнаружил, что моя ошибка использовала else if
вместо elif
вот так:
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
У вас есть открытая цитата, скобка, скобка, если, цикл или что-то еще.
Если вы не можете увидеть его, просто посмотрев (я бы порекомендовал редактор окраски синтаксиса и аккуратный стиль отступов), возьмите копию сценария и удалите половину, вырезав ее где-то, что должно быть допустимым. Если скрипт выполняется настолько далеко, насколько это возможно, то проблема в другой половине. Повторяйте, пока не сузите проблему.
echo"==================PS COMMAND SNAPSHOT=============================================================="
должно быть
echo "==================PS COMMAND SNAPSHOT=============================================================="
Иначе, программа или команда с именем echo"===...
ищется.
больше проблем:
Если вы делаете grep (-A1: + 1 строчный контекст)
grep -A1 "if " cldtest.sh
Вы найдете несколько встроенных ifs и 4 блока if/then.
grep "fi " cldtest.sh
показывает только 3 соответствующих фантастических высказывания. Таким образом, вы забыли один файл тоже.
Я согласен с Camh, что правильный отступ с самого начала помогает избежать таких ошибок. Поиск нужного пути позже означает двойную работу в таком коде спагетти.
Это также может быть вызвано выпуском пары фигурных скобок на линии.
Это не удается:
{ /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
Я столкнулся с той же ошибкой при попытке выполнить файл сценария, созданный в ОС Windows, с помощью textpad. чтобы можно было выбрать подходящий формат файла, например, unix/mac и т. д., или пересоздать скрипт в linux.