Как использовать переменные в цикле bash for
Как использовать переменную в цикле bash for?
Если я просто использую стандарт для цикла, он делает то, что я ожидаю
for i in {0..3}
do
echo "do some stuff $i"
done
Это прекрасно работает. Он проходит через 4 раза, от 0 до 3 включительно, печатает мое сообщение и помещает счет в конце.
do some stuff 0
do some stuff 1
do some stuff 2
do some stuff 3
Когда я пытаюсь сделать то же самое со следующим для цикла, это похоже на строку, которая не то, что я хочу.
length=3
for i in {0..$length}
do
echo "do something right $i"
done
выход:
do something right {0..3}
Я пробовал
for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3})
и
for i in {0..'$length'} (output was {0..$length})
и они оба не делают то, что мне нужно. Надеюсь, кто-то может мне помочь. Заранее благодарим за любую bash экспертную помощь для циклов.
Ответы
Ответ 1
Один из способов: eval
:
for i in $( eval echo {0..$length} )
do
echo "do something right $i"
done
Обратите внимание, что происходит, если вы устанавливаете length=;ls
или length=; rm *
(не пытайтесь использовать последний).
безопасно, используя seq
:
for i in $( seq 0 $length )
do
echo "do something right $i"
done
или вы можете использовать цикл c-style for, который также безопасен:
for (( i = 0; i <= $length; i++ ))
do
echo "do something right $i"
done
Ответ 2
В bash, расширение скобки является первым шагом, предпринятым таким образом, в этот момент $length
не будет заменен.
В manpage для bash четко указано:
Выражение последовательности принимает вид {x..y [.. incr]}, где x и y либо целые числа, либо одиночные символы...
Существует несколько возможностей, таких как использование:
pax> for i in $(seq 0 $length) ; do echo $i ; done
0
1
2
3
хотя это может дать вам большую командную строку, если length
массивный.
Другой альтернативой является использование синтаксиса C-like:
pax> for (( i = 0; i <= $length; i++ )) ; do echo $i; done
0
1
2
3
Ответ 3
Субтитры брейков выполняются перед любыми другими, поэтому вам нужно использовать eval
или
сторонний инструмент, например seq
.
Пример для eval:
for i in `eval echo {0..$length}`; do echo $i; done
Эта информация действительно может быть найдена в man bash
:
Выражение последовательности принимает вид {x..y [.. incr]}, , где x и y являются либо целые числа или одиночные символы, а incr - необязательный приращение - целое число. [...]
Расширение скобки выполняется перед любыми другими расширениями, а любые специальные символы к другим расширениям сохраняются в результате. Это строго текстовое. Bash не применяет синтаксической интерпретации к контексту расширения или текст между фигурными скобками.