У меня есть набор из 100 вопросов. Мое требование: когда пользователь вводит «да», должен появиться вопрос 1. Если нет, сразу переходите к вопросу 2. Таким образом, это должно продолжаться для 100 вопросов. Любые возможные варианты приветствуются.
Этот код, который я пробовал, но безуспешно.
#!/bin/bash
echo "Execute question1 "
select result in Yes No
do
echo "How to see apache config file"
exit
done
echo "execute question2"
select result in Yes No Cancel
do
echo "Command for listing processes"
exit
done
Ответ 1
Вот способ сделать это с помощью массива.
#!/bin/bash
questions=(
"How to see apache config file"
"Command for listing processes"
"My hovercraft is full of eels"
)
for((q=0; q<${#questions[@]}; q++)); do
echo "Execute question $q?"
select result in Yes No; do
case $result in
Yes)
echo "${questions[q]}";;
esac
break
done
done
Однако использование select для этого кажется довольно неуклюжим. Возможно, просто замените его на
read -p "Execute question $q? " -r result
case $result in
[Yy]*) echo "${questions[q]}";;
esac
Просто список вопросов все еще кажется на совсем понятным. С Bash 5+ у вас может быть ассоциативный массив или параллельный массив с такими же индексами и ответами на вопросы. Но лучше всего было бы хранить каждую пару вопросов и ответов вместе в источнике. Лучше всего, перебрать все вопросы и ответы и назначить им специальный answers массив и увеличивать индекс только после прочтения пары?
pairs=(
"How to see Apache config file"
"cat /etc/httpd.conf"
"Command for listing processes"
"ps"
"My hovercraft is full of what?"
"eels"
)
questions=()
answers=()
for((i=0; i<=${#pairs[@]}/2; ++i)); do
questions+=("${pairs[i*2]}")
answers+=("${pairs[1+i*2]}")
done
В итоге для цикла for получаются две копии и вопросов и ответов. Поэтому, если вы действительно ограничены в памяти, возможно, проведите рефакторинг до простого цикла по строкам и избавьтесь от pairs массива, который полезен только во время инициализации.
Ответ 2
Используйте массив вопросов и перебирайте их, например так:
#!/bin/bash
n=1
questions=(
'How to see apache config file'
'Command for listing processes'
)
check_user_input(){
read -p "y/n " input
case $input in
[Yy]*) return 0;;
[Nn]*) return 1;;
*) check_user_input;;
esac
}
for question in "${questions[@]}"; {
echo "Execute question $n"
check_user_input && echo "$question"
((n++))
}
Ответ 3
Вот простой пример. Можете поэкспериментировать с этим.
#!/bin/bash
echo "Type 'y' for yes, 'n' to skip or 'q' to quit and press Enter!"
for((i=1; i < 101; ++i)); do
echo 'Execute question '$i
while read user_input; do
if [[ "$user_input" = 'q' ]]; then
break 2
elif [[ "$user_input" = 'n' ]]; then
break
elif [[ $i -eq 1 ]]; then
echo 'How to see apache config file?'
break 2 # Change from "break 2" to "break" for the next question.
elif [[ $i -eq 2 ]]; then
echo 'Command for listing processes.'
break 2 # Change from "break 2" to "break" for the next question.
else
echo "Wrong input: $user_input"
echo "Type 'y' for yes, 'n' to skip or 'q' to quit and press Enter!"
fi
done
done
echo 'Finished'
Linux