Linux

Да или нет в сценарии Bash

У меня есть набор из 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

Как завершить дочерний процесс по истечении заданного времени ожидания в Bash

Linux

Безопасный стандартный набор правил iptables для базового веб-сервера HTTP(s)

Как произвести DeadBeef настройку: руководство для пользователей
Linux

Как произвести DeadBeef настройку: руководство для пользователей

Linux

Безопасно ли устанавливать make на производственном сервере?

×