bash и его пробелы

Октябрь 13, 2011 at 16:43 Оставьте комментарий

Этот пост о моей темноте. Возможно для кого-то это очевидно, для меня — нет. Мне понадобилось написать скрипт даже не баше, а на шелле, в котором должен был быть цикл while. Первый раз пришлось его использовать. Ну я изучила синтаксис, написала скрипт. Не работает. Ошибка странная:
./test_script: 6: Syntax error: «done» unexpected (expecting «do»)
Опытным путем поняла первую интересную вещь: do, видимо, является отдельным оператором, поэтому просто написать

while [ $i -le 3 ] do

нельзя! Если уж пишем так, то надо ставить точку с запятой перед do, либо переносить его на следующую строчку.
После этого появилась новая штука:
./test_script: 7: [1: not found
7 — это номер строки скрипта, в котором найдена ошибка
[1 — это виновник ошибки
not found — описание ошибки.
Все это довольно загадочно, потому что на седьмой строке нету [1.
Чтобы все было понятно, приведу тестовый скрипт, иллюстрирующий задачу.

#!/bin/sh
i=1
while [ $i -le 10 ]
do
    echo "Hello"
    i=`expr $i + 1`
done

Этот скрипт работает!
А вот этот нет:

#!/bin/sh
i = 1
while [ $i -le 10 ]
do
    echo "Hello"
    i = `expr $i + 1`
done

Такой вариант выдаст ошибку
./test_script: 2: i: not found[: 7: -le: unexpected operator
А вот этот вообще зацикливается с ошибкой ./test_script: 7: i: not found

#!/bin/sh
i=1
while [ $i -le 10 ]
do
    echo "Hello"
    i = `expr $i + 1`
done

В чем отличие? В пробелах! Оказывается, shell по-разному интерпретирует знак равенства в зависимости от того, окружен он пробелами или нет(один пробел считается как наличие пробелов). Если пробелов нет, то выполняется операция присвоения, то есть именно то, что нужно. А если пробелы есть, то shell пытается выполнить команду i с аргументами = и значением выражения expr.
То же самое произойдет, если в теле цикла выполнять присвоение переменной i вот так:

 $i=`expr $i + 1`

В этом случае ошибка будет примерно такая:
./test_script: 7: 1=2: not found
А все потому, что shell вычислит значение i. На первом шаге в нем лежит 1. Затем вычислит значение выражения — это будет 2. А потом попробует выполнить команду 1 с параметрами =2.

Реклама

Entry filed under: Linux. Tags: , , , , , .

Сброс сессий терминалов в XP. lm-sensors в vyatta

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed



%d такие блоггеры, как: