Подтвердить что ты не робот

Использование переменной в диапазоне расширения скобок, подаваемой в цикл for

Вот 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} напрямую?

4b9b3361

Ответ 1

Для выполнения этого цикла вы должны использовать цикл цикла C:

for ((i=1; i<=$1; i++)); do
   echo $i
done

Это позволяет избежать внешних команд и неприятных утверждений eval.

Ответ 2

Поскольку расширение расширений происходит до расширения переменных. http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion.

Если вы хотите использовать фигурные скобки, вы можете сделать что-то мрачное, как это:

for i in `eval echo {1..$1}`;
do
    echo $1 $i;
done

Резюме: Bash является подлым.

Ответ 3

Вы можете использовать команду seq:

for i in `seq 1 $1`

Или вы можете использовать стиль C for...loop:

for((i=1;i<=$1;i++))

Ответ 4

Вот способ расширения переменных внутри фигурных скобок без eval:

end=3
declare -a 'range=({'"1..$end"'})'

Теперь у нас есть хороший массив чисел:

for i in ${range[@]};do echo $i;done
1
2
3

Ответ 5

Я знаю, что вы упоминали bash в заголовке, но я бы добавил, что "для я в {$ 1.. $2}" работает так, как предполагалось в zsh. Если ваша система имеет zsh, вы можете просто изменить свой shebang на zsh.

Использование zsh с примером 'для я в {$ 1.. $2}' также имеет дополнительное преимущество: $1 может быть меньше $2, и он все еще работает, что потребует довольно много беспорядков, если вы хотите, чтобы гибкость с циклом C-стиля.