Я пишу этот скрипт оболочки bash:
#!/bin/bash
declare -i N
read N
for i in {1..$N}
do
echo "Number: $i"
done
(Я считаю, declare -i N
что это N
целое число)
Однако при запуске я получаю следующий вывод:
>vim new.sh
>chmod +x passgen.sh
>./passgen.sh
15
Number: {1..15}
Здесь я хочу взять лимит у пользователя, а затем запустить цикл.
решение1
От man bash
:
Порядок расширений следующий: расширение фигурных скобок; расширение тильды, расширение параметров и переменных, арифметическое расширение и подстановка команд (выполняется слева направо); разделение слов; и расширение имени пути.
Как вы видите, сначала идет раскрытие скобок, так что, по-видимому, в вашей задаче оно пропущено. Я бы вместо этого использовал другой цикл.
решение2
Хотя проблема с расширением скобок уже была обозначена, я просто прокомментирую:
(Я считаю, что declare -i N делает N целым числом)
Я отвечу, да, это так, и это проблема, поскольку это делает уязвимость инъекции команд. С этим набором целочисленных атрибутов, всякий раз, когда переменной присваивается значение, это значение интерпретируется как арифметическое выражение.
Если пользователь введет a[$(reboot)]
это read
приглашение, это вызовет, например, попытку перезагрузки.
Это общая проблема с bash
, zsh
и ksh
всякий раз, когда оцениваются арифметические выражения. Даже использование for (( i = 1; i <= N; i++ ))
формы в стиле ksh93 (с или без declare -i N
) было бы проблемой, поскольку содержимое N
все равно оценивается в этом арифметическом контексте.
for i in {1..$N}
будет нормально (без declare -i N
) в ksh, zsh или yash -o braceexpand
(будет зацикливаться на бессмысленной фразе, но не приведет к уязвимости внедрения команд), или вы можете использовать стандартный sh
синтаксис, при условии, что ваша sh
реализация не основана на ksh
.
#! /bin/sh -
IFS= read -r N
i=1; while [ "$i" -lt "$N" ]; do
printf '%s\n' "Number: $n"
done
ksh
's [
по-прежнему обрабатывает операнд -lt
как арифметические выражения, поэтому все равно будет вносить уязвимости инъекции команд. Не используйте [[ $i -lt $N ]]
или (( i < N ))
в bash
/ zsh
/ ksh
, которые также имеют проблему.
Или вы можете использовать awk
/ perl
или любой подходящий язык программирования для реализации цикла, или вы можете сначала очистить входные данные.