Я испытываю затруднения при получении, чтобы цикл взял ввод данных пользователем в форме аргумента функции, которую я создал.
#!/bin/bash
number1="$1" #Assume user input 5
loops="$2" #Assume user input 5
if [[ ${number1} && ${loops} =~ ^-?[0.00-9.99]+$ ]];then
for number2 in {1..${loops}}
do
Product=$(echo "${number1} * ${number2}" | bc -l)
echo "${number1} * ${number2} = ${Product}"
if test ${number2} -eq 7;then
{ echo "----------------------"; echo "${number2} is the best number."; echo "----------------------"; continue; }
elif test ${number2} -eq 11;then
{ echo "------------------------------"; echo "${number2} is pretty awesome as well."; echo "------------------------------"; continue; }
fi
done
else
{ echo "Please try again with a valid numerical entry."; exit 1; }
fi
Этот сценарий не работает когда вводы данных пользователем целое число для переменных "циклов" и любое число для "number1". number1 = 5 в этом случае. Это возвращает ошибку:
(standard_in) 1: синтаксическая ошибка
5 * {1.. 5} =
/home/$USER/For_Loop_Multiplication.sh: строка 9: тест: {1.. 5}: целое выражение ожидается
/home/$USER/For_Loop_Multiplication.sh: строка 11: тест: {1.. 5}: целое выражение ожидается
Если я вместо этого непосредственно ввел конец, привязал количество циклов непосредственно в сценарий как следующее и number1 = 5, это хорошо работает:
#!/bin/bash
number1="$1" #Assume user input 5
if [[ ${number1} =~ ^-?[0.00-9.99]+$ ]];then
for number2 in {1..5}
do
Product=$(echo "${number1} * ${number2}" | bc -l)
echo "${number1} * ${number2} = ${Product}"
if test ${number2} -eq 7;then
{ echo "----------------------"; echo "${number2} is the best number."; echo "----------------------"; continue; }
elif test ${number2} -eq 11;then
{ echo "------------------------------"; echo "${number2} is pretty awesome as well."; echo "------------------------------"; continue; }
fi
done
else
{ echo "Please try again with a valid numerical entry."; exit 1; }
fi
Это возвращает результат:
5 * 1 = 5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
По существу то, что я думаю, происходит, то, что сценарий, кажется, помещает весь диапазон как значение number2, который определяется как итератор в для цикла. Так как вход для переменных "циклов" является целым числом, не должно быть никакого различия между выяснением у пользователя для диапазона и размещением его в цикле или просто установке его как значение по умолчанию, когда я пишу сценарий. Однако, по-видимому, существует различие... Любое понимание решения этой проблемы ценится.Спасибо.
Проблемой является эта строка:
for number2 in {1..${loops}}
Это - вопрос приоритета. Как объяснено в man bash
:
порядок расширений: расширение фигурной скобки; расширение тильды, параметр и переменное расширение, арифметическое расширение и замена команды (выполненный слева направо вид); разделение слова; и расширение пути.
Так, расширение фигурной скобки происходит прежде переменное расширение. Поэтому, когда фигурные скобки расширены, $loops
не был оценен к 5
. Это означает, что {1..$loops}
(Вам не нужно второе {}
) расширяется до строки {1..5}
а не последовательность чисел от 1 до 5. То же самое происходит при использовании строки вместо переменной:
$ echo {1..5} ## works: prints a sequence
1 2 3 4 5
$ echo {1..foo} ## fails: prints a string with no expansion
{1..foo}
Как обходное решение, можно использовать seq
:
for number2 in $(seq 1 "$loops"); do ...
Или, еще лучше, правильный цикл для задания:
for((number2=0;number2<=$loops; number2++)); do ...
Примечание: Как правило, необходимо также всегда заключать переменные в кавычки.