обсуждение
Использование seq
хорошо, как предложил Джиаро. Pax Diablo предложил цикл Bash, чтобы избежать вызова подпроцесса, с дополнительным преимуществом большей дружественности памяти, если $ END слишком велик. Затрус заметил типичную ошибку в реализации цикла, а также намекнул, что, поскольку i
является текстовой переменной, непрерывное преобразование чисел туда-сюда выполняется с соответствующим замедлением.
целочисленная арифметика
Это улучшенная версия цикла Bash:
typeset -i i END
let END=5 i=1
while ((i<=END)); do
echo $i
…
let i++
done
Если единственное, что нам нужно, это echo
, то мы могли бы написать echo $((i++))
.
ephemient научил меня кое-чему: Bash допускает for ((expr;expr;expr))
конструкции. Поскольку я никогда не читал всю справочную страницу по Bash (как я делал с справочной страницей оболочки Korn (ksh
), и это было давно), я пропустил это.
Итак,
typeset -i i END # Let's be explicit
for ((i=1;i<=END;++i)); do echo $i; done
кажется наиболее эффективным способом использования памяти (нет необходимости выделять память для использования вывода seq
, что может быть проблемой, если END очень большой), хотя, вероятно, не самый «быстрый» .
начальный вопрос
eschercycle отметил, что нотация { a .. b } Bash работает только с литералами; правда, в соответствии с руководством Bash. Это препятствие можно преодолеть с помощью одного (внутреннего) fork()
без exec()
(как в случае с вызовом seq
, который для другого изображения требует форка + exec):
for i in $(eval echo "{1..$END}"); do
Оба eval
и echo
являются встроенными командами Bash, но для подстановки команд требуется fork()
(конструкция $(…)
).