Ответ 1
Для выполнения этого цикла вы должны использовать цикл цикла C:
for ((i=1; i<=$1; i++)); do
echo $i
done
Это позволяет избежать внешних команд и неприятных утверждений eval.
Вот myscript.sh
#!/bin/bash
for i in {1..$1};
do
echo $1 $i;
done
Если я запустил myscript.sh 3
, выход будет
3 {1..3}
вместо
3 1
3 2
3 3
Ясно, что $3
содержит правильное значение, так почему же for i in {1..$1}
ведет себя так же, как если бы я написал for i in {1..3}
напрямую?
Для выполнения этого цикла вы должны использовать цикл цикла C:
for ((i=1; i<=$1; i++)); do
echo $i
done
Это позволяет избежать внешних команд и неприятных утверждений eval.
Поскольку расширение расширений происходит до расширения переменных. http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion.
Если вы хотите использовать фигурные скобки, вы можете сделать что-то мрачное, как это:
for i in `eval echo {1..$1}`;
do
echo $1 $i;
done
Резюме: Bash является подлым.
Вы можете использовать команду seq
:
for i in `seq 1 $1`
Или вы можете использовать стиль C for...loop
:
for((i=1;i<=$1;i++))
Вот способ расширения переменных внутри фигурных скобок без eval:
end=3
declare -a 'range=({'"1..$end"'})'
Теперь у нас есть хороший массив чисел:
for i in ${range[@]};do echo $i;done
1
2
3
Я знаю, что вы упоминали bash в заголовке, но я бы добавил, что "для я в {$ 1.. $2}" работает так, как предполагалось в zsh. Если ваша система имеет zsh, вы можете просто изменить свой shebang на zsh.
Использование zsh с примером 'для я в {$ 1.. $2}' также имеет дополнительное преимущество: $1 может быть меньше $2, и он все еще работает, что потребует довольно много беспорядков, если вы хотите, чтобы гибкость с циклом C-стиля.