2013-11-18 2 views
-1

Это просто проблема, но я не понимаю, почему я получил ошибку здесь. Это всего лишь цикл for внутри оператора if.Неожиданный конец файла bash script

Это мой код:

#!/bin/bash 
if (!(-f $argv[1])) then 
    echo "Argv must be text file"; 
else if ($#argv != 1) then 
    echo "Max argument is 1"; 
else if (-f $argv[1]) then 
    for i in `cut -d ',' -f2 $argv[1]` 
     do 
     ping -c 3 $i; 
     echo "finish pinging host $i" 
    done 
fi 

Ошибка в строке 16, которая является линией после fi, то есть пустая строка .....

Может кто-то пожалуйста, объясните, почему у меня есть эта ошибка ????

+1

Чтобы ответить на личный вопрос: 'else if' не совпадает с' elif', потому что он оставляет ваш первый 'if/then/else' блок открытым при запуске второго, поэтому вам нужно _two_' ends', поэтому вы получаете неожиданный EOF. –

ответ

0

Для каждого открытия if у вас должно быть соответствующее закрытие fi. Это справедливо и для else if. Лучше использовать elif вместо

if test ! -f "$1"; then 
    echo "Argv must be text file"; 
elif test $# != 1; then 
    echo "Max argument is 1"; 
elif test -f "$1"; then 
    for i in `cut -d ',' -f2 "$1"` 
    do 
     ping -c 3 $i; 
     echo "finish pinging host $i" 
    done 
fi 
  • Там также нет argv переменной. Если вы хотите получить доступ к аргументам командной строки, вы должны использовать $1, $2 ...
  • Следующая точка $#argv, это имеет значение $# (количество командной строки арг) и argv. Это очень похоже на perl.
  • Кроме того, тестирование проводится либо с test ... или [ ... ], не (...)
  • И, наконец, вы должны заключить по крайней мере, ваши аргументы командной строки в двойных кавычках "$1". Если у вас нет и нет аргументов командной строки, то есть, например

    test ! -f 
    

    вместо

    test ! -f "" 
    

    Это позволяет тест неудачу и перейти к второй, если, вместо того, вторя надлежащее сообщение.

+0

в моем слайде лекции, аргумент отмечен argv .... –

+0

а также, я попробовал elif, но эта ошибка все еще появляется –

+0

У вас все еще есть ошибки в этом скрипте, но не 'неожиданный конец файла'. –

2

много, много ошибки.

Если я стараюсь держаться как можно ближе к примеру код:

#!/bin/sh 
if [ ! -f "${1}" ] 
then 
    echo "Argv must be text file"; 
else if [ "${#}" -ne 1 ] 
    then 
     echo "Max argument is 1"; 
    else if [ -f "${1}" ] 
      then 
      for i in $(cat "${1}" | cut -d',' -f2) 
      do 
       ping -c 3 "${i}"; 
       echo "finish pinging host ${i}" 
      done 
      fi 
    fi 
fi 

другой путь, выходя каждый раз, когда условие не выполнено:

#!/bin/sh 
[ "${#}" -ne 1 ] && { echo "There should be 1 (and only 1) argument" ; exit 1 ; } 
[ ! -f "${1}" ] && { echo "Argv must be a file." ; exit 1 ; } 
[ -f "${1}" ] && { 
    for i in $(cat "${1}" | cut -d',' -f2) 
    do 
     ping -c 3 "${i}"; 
     echo "finish pinging host ${i}" 
    done 
} 
+0

Отсутствие причин для дополнительных фигурных скобок - они не имеют никакой цели, если не параметризуют расширение или неоднозначность границ токена. –

+0

... и если вы собираетесь использовать shebang '/ bin/bash', также можете использовать операторы bash:' else if (($ #> 1)) 'легче читать. –

+0

... и более эффективно не использовать cat; если вы _must_ используете cut: 'cut -d, -f2 <" $ 1 "' –

0
#!/usr/local/bin/bash -x 

if [ ! -f "${1}" ] 
    then 
    echo "Argument must be a text file." 
else 
    while-loop-script "${1}" 
fi 

Я сломанный это вверх, потому что я лично считаю чрезвычайно плохую форму, чтобы вложить одну функцию внутри другой; или правдиво даже иметь более одной функции в одном файле. Я не забочусь о размере файла; У меня есть несколько скриптов длиной 300-500 байт. Я изучаю FORTH; фрактализм в этом смысле является добродетелью.

# while-loop-script 

while read line 
    do 
    IFS="@" 
    ping -c 3 "${line}" 
    IFS=" "   
done < "${1}" 

Не используйте cat для подачи отдельных строк файла в скрипт; он всегда будет терпеть неудачу, и bash попытается выполнить вывод как буквенную команду. Я думал, что печать sed будет работать, и это часто происходит, но по какой-то причине она очень часто заменяет пространства для новых строк, что также крайне раздражает.

Единственный абсолютно пуленепробиваемый способ подачи строки на скрипт, который я знаю, который сохранит все пространство и форматирование, заключается в использовании циклов while-read, а не вместо кота или для циклов sed, как уже упоминалось.

Что-то еще, что вам нужно сделать, чтобы быть уверенным в сохранении пробелов, заключается в том, чтобы установить внутренний разделитель полей (IFS) на то, что вы знаете, ваш файл не будет содержать, а затем сбросить его обратно в пробелы в конце цикла.

+0

Почему вы меняете 'IFS'? Единственная команда здесь, которая обращает внимание на ее значение, является 'read', и вы можете установить IFS только для продолжительности этой одной команды, а не для изменения значения оболочки вообще. –

+1

... на другой ноте ваш shebang будет более переносимо написан как '#!/Usr/bin/env bash', с' set -x' на отдельной строке. –

+0

Файл, который я использовал в качестве примера для разработки этого скрипта, был макетом, который я написал некоторое время назад, и имел вкладки в начале каждой строки. Я обнаружил, что изменение IFS было единственным способом сохранить начальную вкладку, которая в некоторых ситуациях я бы хотел. Также, спасибо за разъяснение линии bash. – petrus4

Смежные вопросы