2012-05-10 2 views
6

Я пытаюсь узнать сценарии оболочки, поэтому я создал простой скрипт с петлей, которая ничего не делает:Смешение ошибки синтаксиса около неожиданной лексемы «сделали»

#!/bin/bash 
names=(test test2 test3 test4) 
for name in ${names[@]} 
do 
     #do something 
done 

Однако, когда я запускаю этот скрипт я получаю следующие ошибки:

./test.sh: строка 6: ошибка синтаксиса около неожиданной лексемы сделано '
./test.sh: линия 6: сделано'

Что я пропустил здесь? являются ли вкладки с вкладками «вкладки»?

+0

Просто посмотрите один раз http://stackoverflow.com/a/42478844/6545759 Может быть полезно –

ответ

5

Нет, скрипты оболочки не чувствительны к табуляции (если вы не делаете что-то действительно сумасшедшее, чего вы не делаете в этом примере).

Вы не можете иметь пустой 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 
+0

спасибо, что works =), есть ли способ получить все выходные данные в одной строке? – fenerlitk

+1

Я рад, что помог. См. Мое редактирование. Удачи. – shellter

+0

Я только что видел это, большое спасибо :) – fenerlitk

1

Вместо этого вы можете заменить ничего «истинным».

+0

Что вы имеете в виду тем? – fenerlitk

+2

делать правду; сделано ... но почему ваша петля пуста? –

4

dash и bash немного мозга -dead в этом случае, они не допускают пустой цикл, поэтому вам нужно добавить команду no op для выполнения этого запуска, например true или :. Мои тесты предполагают, что : немного быстрее, although they should be the same, не знаю, почему:

time (i=100000; while ((i--)); do :; done) 

н среднем занимает 0.262 секунд, в то время как:

time (i=100000; while ((i--)); do true; done) 

занимает 0.293 секунд. Любопытно:

time (i=100000; while ((i--)); do builtin true; done) 

занимает 0.356 секунд.

Все измерения в среднем составляют 30 пробегов.

+2

Я бы назвал не обработкой пустой петли функцию! ;-) Всем удачи. – shellter

+0

@shellter: Обработка не прекрасна, поэтому синтаксическая ошибка не является – Thor

1

У вас должно быть что-то в вашей петле, иначе жаль жалуется.

3

У Bash есть встроенный no-op, толчок (:), который является более легким , чем нерестится другой процесс для запуска true.

#!/bin/bash 
names=(test test2 test3 test4) 
for name in "${names[@]}" 
do 
    : 
done 

EDIT: Уильям правильно указывает, что true также оболочка встроенной, так что принять этот ответ, как только другой вариант FYI, не лучшее решение, чем использование верно.

+1

: это правильный не-op, но 'true' был встроенным в течение длительного времени. Я полагаю, что очень мало снарядов, используемых сегодня, порождают новый процесс. –

+0

Bash ':' как Python 'pass' инструкция – Stphane

+0

Также отметить (5 лет спустя),': 'is * required * от POSIX, чтобы быть встроенным, в то время как' true' является только опциональным (но я делаю ставку почти всегда) встроенный. – chepner

0

Эта ошибка, как ожидается, с некоторыми версиями Баша, где сценарий был отредактированные на 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 выше один символ возврата каретки, чтобы ввести его в последовательность использования редактора Control-V Control-M)

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