Синтаксическая ошибка около неожиданного токена `fi`

Синтаксическая ошибка около неожиданного токена `fi`

Мне не обязательно нужен ответ, но если кто-то может указать мне на какую-то литературу или примеры, я бы хотел разобраться.

При запуске скрипта возникает ошибка:

Синтаксическая ошибка около неожиданного токенаfi

Я пришел к выводу, что проблема в моем ifутверждении, сделав ifкомментарии к утверждениям и добавив, echo "$NAME"которые отображают имена в /etc/.

Когда я вношу изменения, удаляю #from ifи fiи добавляю #to wc -c "$NAME", я получаю синтаксическую ошибку, которую я перечислил выше. Я добавил ;между ]then. Я также перешел thenна следующую строку без разрешения.

#!/bin/bash
for NAME in /etc/*
do

     if [ -r "$NAME" -af "$NAME" ] then
          wc -c "$NAME"
     fi
done

решение1

Ключевые слова, такие как if, then, else, fi, for, caseи т. д. должны находиться в том месте, где оболочка ожидает имя команды. В противном случае они рассматриваются как обычные слова. Например,

echo if

просто печатает if, а не начинает условную инструкцию.

Таким образом, в строке

if [ -r "$NAME" -af "$NAME" ] then

слово thenявляется аргументом команды [(на что она бы пожаловалась, если бы когда-нибудь ее запустили). Оболочка продолжает искать then, и находит fiв командной позиции. Поскольку есть , ifкоторый все еще ищет свой then, то fiэто неожиданно, это синтаксическая ошибка.

Вам нужно поставить перед ним разделитель команды, thenчтобы он был распознан как ключевое слово. Наиболее распространенным разделителем команды является перенос строки, но перед ним thenобычно используют точку с запятой (которая имеет точно такое же значение, как и перенос строки).

if [ -r "$NAME" -af "$NAME" ]; then

или

if [ -r "$NAME" -af "$NAME" ]
then

Как только вы это исправите, вы получите еще одну ошибку от команды, [потому что она не понимает -af. Вы, вероятно, имели в виду

if [ -r "$NAME" -a -f "$NAME" ]; then

Хотя тестовые команды выглядят как опции, вы не можете объединить их таким образом. Они являются операторами команды [и должны быть отдельными словами (как [и ]).

Кстати, хотя [ -r "$NAME" -a -f "$NAME" ]работает, я рекомендую писать либо

[ -r "$NAME" ] && [ -f "$NAME" ]

или

[[ -r $NAME && -f $NAME ]]

Лучше всего сохранять [ … ]условные операторы простыми, поскольку [команда не может легко отличить операторы от операнда. Если $NAMEвыглядит как оператор и появляется в позиции, где оператор допустим, он может быть проанализирован как оператор. Этого не произойдет в простых случаях, рассмотренных в этом ответе, но более сложные случаи могут быть рискованными. Написание этого с отдельными вызовами [и использование логических операторов оболочки позволяет избежать этой проблемы.

Второй синтаксис использует [[ … ]]условную конструкцию, которая существует в bash (и ksh и zsh, но не в чистом sh). Эта конструкция является специальным синтаксисом, хотя [разбирается как любая другая команда, поэтому вы можете использовать такие вещи, как &&внутри, и вам не нужно заключать переменные в кавычки, за исключением аргументов некоторых строковых операторов ( =, ==, !=, =~) (см.Когда необходимо двойное кавычивание?для получения подробной информации).

решение2

Посмотрите, что изменилось:

если [ -r "$ИМЯ"-а -ф"$ИМЯ" ];затем
# ^^^^^^ ^
     wc -c "$ИМЯ"
фи

Если вы хотите удалить все команды в блоке if, вам как минимум нужно добавить в него двоеточие, например:

if [ -r "$NAME" -a -f "$NAME" ]; then
    :
fi

или однострочная версия

if [ -r "$NAME" -a -f "$NAME" ]; then :; fi

решение3

Другие уже указывали, но если вы ищете официальную ссылку, тоРТМ

если список; тогда список; [ elif список; тогда список; ] ... [ иначе список;] fi

Список if выполняется. Если его статус выхода равен нулю, выполняется список then. В противном случае каждый список elif выполняется по очереди, и если его статус выхода равен нулю, выполняется соответствующий список then, и команда завершается. В противном случае выполняется список else, если он присутствует. Статус выхода — это статус выхода последней выполненной команды или ноль, если ни одно из проверенных условий не является истинным.

Вам не хватает;

И синтаксис дляlistописано вman test

Связанный контент