Запутанная синтаксическая ошибка рядом с неожиданной знак 'Сделано'
Я пытаюсь узнать сценариев оболочки, поэтому я создал простой скрипт с циклом, который ничего не делает:
#!/bin/bash
names=(test test2 test3 test4)
for name in ${names[@]}
do
#do something
done
однако, когда я запускаю этот скрипт я получаю следующие ошибки:
./test.sh: строка 6: синтаксическая ошибка рядом с неожиданным токеном"
. /test.sh: строка 6: готово'
что я пропустил здесь? вкладка shell-скрипты "чувствительные"?
6 ответов
нет, сценарии оболочки не чувствительны к вкладке (если вы не делаете что-то действительно сумасшедшее, чего вы не делаете в этом примере).
вы не можете иметь пустой while do done
блок, (комментарии не в счет)
Попробуйте заменить echo $name
вместо
#!/bin/bash
names=(test test2 test3 test4)
for name in ${names[@]}
do
printf "%s " $name
done
printf "\n"
выход
test test2 test3 test4
dash
и bash
немного мозг мертв в этом случае, они не позволяют пустой цикл, поэтому вам нужно добавить команду no op, чтобы сделать этот запуск, например true
или :
. Мои тесты предполагают :
немного быстрее, хотя они должны быть одинаковыми не знаю, почему:
time (i=100000; while ((i--)); do :; done)
средняя N принимает 0.262
секунд, в то время как:
time (i=100000; while ((i--)); do true; done)
принимает 0.293
секунд. Интересно:
time (i=100000; while ((i--)); do builtin true; done)
принимает 0.356
считанные секунды.
все измерения в среднем 30 пробегов.
Bash имеет встроенный no-op, двоеточие (:), которое является более легким
чем нерест другого процесса для запуска true
.
#!/bin/bash
names=(test test2 test3 test4)
for name in "${names[@]}"
do
:
done
EDIT: Уильям правильно указывает, что true
также является встроенной оболочкой, поэтому возьмите этот ответ как еще один вариант FYI, а не лучшее решение, чем использование true.
эта ошибка ожидается с некоторыми версиями bash, где скрипт был отредактирован в Windows, и поэтому скрипт на самом деле выглядит следующим образом:
#!/bin/bash^M
names=(test test2 test3 test4)^M
for name in ${names[@]}^M
do^M
printf "%s " $name^M
done^M
printf "\n"^M
где ^M представляет символ возврата каретки (0x0D). Это можно легко увидеть в vi, используя двоичный параметр, как в:
vi -b script.sh
чтобы удалить эти символы возврата каретки, просто используйте команду vi:
1,$s/^M//
(обратите внимание, что ^M выше является одним символом возврата каретки, чтобы ввести его в редактор использует sequence Control - V Control-M)