2015-12-11 3 views
3

У меня есть сценарий с именем build_other:Вызов внутреннего сценария из внешнего сценария

count=0 
while [ $count -lt 6 ] 
do 
    ./build 
    count+=1 
done 

Из этого сценария, вы можете видеть, что я звоню второй сценарий, названный build:

echo "building job" 
sleep 30s 
echo "wake after sleep" 
echo "file build" >> output.txt 

Я ожидаю, что build должен срабатывать 5 раз, потому что count увеличивается на 1 после build работает. Это означает, что output.txt должен иметь 5 строк, обозначающих file build. Ниже представлен вывод, который я действительно получил.

building job 
wake after sleep 
building job 
wake after sleep 

Файл output.txt имеет только две строки в нем.

file build 
file build 

Почему цикл не работает 5 раз, как я ожидал?

+0

Повторите свой сценарий с 'declare -i count = 0' и см. Ответ Дэна ниже для полного объяснения. –

ответ

3

Оператор += не делает то, что вы здесь думаете; он не является оператором «add to», он действует как оператор конкатенации строк.

$ ./foo.sh 
./build 
count is now 01 
./build 
count is now 011 

После двух итераций count является 011. Используя числовой оператор меньше -lt, строка 011 преобразуется в числовое значение 11. Так как 11 не меньше 6, контур заканчивается.

Предполагая, что вы используете bash или другую современную оболочку семейства Bourne, вы можете решить это несколькими способами.

# Using arithmetic expansion -- $((expression)) 
count=$((count + 1)) 

# Increment variable in an arithmetic evaluation context -- (()) 
((count++)) 

# When declaring count, declare that it is an integer value. Declared an 
# integer, the += operator will behave as you originally expected it would. 
declare -i count=0 

Несколько выдержек из справочной страницы bash приведены ниже.

О поведении += оператора:

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

Об оценке арифметической:

Арифметическое расширение позволяет вычислять арифметические выражения и подстановки результата.Формат для расширения арифметика:

$((expression))

старого формат $[expression] устарел и будет удален в будущих версиях Баша.

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

В контексте оценки арифметического:

((expression))

Выражение вычисляется в соответствии с правилами, описанными ниже в разделе Арифметические вычисления. Если значение выражения не равно нулю, статус возврата равен 0; в противном случае статус возврата равен 1. Это в точности эквивалентно «выражению».

+1

Хороший ответ. Вы можете упомянуть пару альтернатив прямому назначению типа '((count ++))' или просто установить флаг * integer * на 'count' (например,' declare -i count = 0'). Тем не менее, это стоит голоса. (также, просто nit, при копировании man-страниц, проверьте переносы (например, «varible»), чтобы сделать его лучше читаемым - я знаю, что они боль ...) –

+0

Хорошие предложения; Я включил обе альтернативы, фиксированную перенос и добавил еще несколько отрывков bash (1). –

+0

Один вопрос три ответа и так хорошее объяснение Спасибо Dan Lowe он решил мою проблему и три решения, разработанные для меня – Kirit

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