У меня есть следующий скрипт bash:
#!/bin/bash
upperlim=10
for i in {0..10}
do
echo $i
done
for i in {0..$upperlim}
do
echo $i
done
Первый for
цикл ( без переменной upperlim
в контроле цикла) работает нормально, а второй for
цикл ( с переменной upperlim
в контроле цикла) - нет. Есть ли способ, которым я могу изменить второй for
цикл, чтобы он работал? Спасибо за ваше время.
bash
shell
shell-script
for
Андрей
источник
источник
for i in {0..$((upperlim))}; do echo $i; done
не работаетОтветы:
Причиной этого является порядок, в котором вещи происходят в bash. Разбивка скобок происходит до раскрытия переменных. Чтобы достичь цели, вам нужно использовать цикл C в стиле:
источник
zsh
как хорошо (но не дляcsh
,tcsh
).Чтобы выполнить это в своем стиле, используя только встроенные модули, вам нужно использовать eval:
Но с
seq
:Лично я считаю использование
seq
более читабельным.источник
seq
является внешней командой и недоступна везде, где есть bash.seq
», признавая, что это не встроенный.read
является встроенным, например, но нет никаких оснований дляeval
этого.Способ POSIX
Если вы заботитесь о переносимости, используйте пример из стандарта POSIX :
Выход:
Вещи, которые не POSIX:
(( ))
без доллара, хотя это общее расширение, упомянутое самим POSIX .[[
,[
здесь достаточно Смотрите также: https://stackoverflow.com/questions/13542832/bash-if-difference-between-square-brackets-and-double-square-bracketsfor ((;;))
seq
{start..end}
и это не может работать с переменными, как упомянуто в руководстве по Bash .let i=i+1
: POSIX 7 2. Язык командной оболочки не содержит словаlet
, и он не работает наbash --posix
4.3.42доллар в
i=$i+1
может потребоваться, но я не уверен. POSIX 7 2.6.4 Арифметическое расширение говорит:но, читая его буквально, это не означает, что он
$((x+1))
расширяется, посколькуx+1
не является переменной.источник
Ваш подход не будет работать, так как в bash скобка-расширение происходит перед расширением параметра. Вы должны расширить переменную раньше.
Вы можете работать с eval :
С циклом «Пока» :
Также вы можете сделать это с помощью команды seq :
Если вы хотите работать с
for i in {0..$upperlim}
вами, вам нужно будет использовать kornshell. например:источник