Как мне запросить Да / Нет / Отменить ввод в сценарии оболочки Linux? - PullRequest
1267 голосов
/ 22 октября 2008

Я хочу приостановить ввод в сценарии оболочки и предложить пользователю выбор. Стандартный вопрос типа «Да, Нет или Отмена». Как мне сделать это в типичной командной строке?

Ответы [ 28 ]

3 голосов
/ 22 октября 2008

Я предлагаю вам использовать диалог ...

Ученик Linux: улучшение сценариев Bash Shell с помощью диалога

Команда dialog позволяет использовать оконные блоки в сценариях оболочки, чтобы сделать их использование более интерактивным.

это просто и удобно в использовании, также есть версия gnome, называемая gdialog, которая принимает те же параметры, но показывает стиль GUI на X.

3 голосов
/ 29 июля 2015

более общий будет:

function menu(){
    title="Question time"
    prompt="Select:"
    options=("Yes" "No" "Maybe")
    echo "$title"
    PS3="$prompt"
    select opt in "${options[@]}" "Quit/Cancel"; do
        case "$REPLY" in
            1 ) echo "You picked $opt which is option $REPLY";;
            2 ) echo "You picked $opt which is option $REPLY";;
            3 ) echo "You picked $opt which is option $REPLY";;
            $(( ${#options[@]}+1 )) ) clear; echo "Goodbye!"; exit;;
            *) echo "Invalid option. Try another one.";continue;;
         esac
     done
     return
}
3 голосов
/ 08 апреля 2015

Один простой способ сделать это с помощью xargs -p или GNU parallel --interactive.

Мне нравится поведение xargs немного лучше, потому что оно выполняет каждую команду сразу после приглашения, как и другие интерактивные команды Unix, вместо того, чтобы собирать дачи для выполнения в конце. (Вы можете нажать Ctrl-C после того, как пройдете те, которые вы хотели.)

например,

echo *.xml | xargs -p -n 1 -J {} mv {} backup/
2 голосов
/ 08 ноября 2016

В таком сценарии я пару раз использовал оператор case, и использование статистики случая - хороший способ для этого. Цикл while, который эккапсулирует блок case, который использует логическое условие, может быть реализован для обеспечения еще большего контроля над программой и выполнения многих других требований. После того как все условия будут выполнены, можно использовать break, который вернет управление в основную часть программы. Кроме того, для выполнения других условий, конечно, могут быть добавлены условные операторы, сопровождающие управляющие структуры: case оператор и возможный while цикл.

Пример использования оператора case для выполнения вашего запроса

#! /bin/sh 

# For potential users of BSD, or other systems who do not
# have a bash binary located in /bin the script will be directed to
# a bourne-shell, e.g. /bin/sh

# NOTE: It would seem best for handling user entry errors or
# exceptions, to put the decision required by the input 
# of the prompt in a case statement (case control structure), 

echo Would you like us to perform the option: "(Y|N)"

read inPut

case $inPut in
    # echoing a command encapsulated by 
    # backticks (``) executes the command
    "Y") echo `Do something crazy`
    ;;
    # depending on the scenario, execute the other option
    # or leave as default
    "N") echo `execute another option`
    ;;
esac

exit
2 голосов
/ 24 сентября 2013
yn() {
  if [[ 'y' == `read -s -n 1 -p "[y/n]: " Y; echo $Y` ]];
  then eval $1;
  else eval $2;
  fi }
yn 'echo yes' 'echo no'
yn 'echo absent no function works too!'
2 голосов
/ 04 июня 2015

В качестве друга однострочной команды я использовал следующее:

while [ -z $prompt ]; do read -p "Continue (y/n)?" choice;case "$choice" in y|Y ) prompt=true; break;; n|N ) exit 0;; esac; done; prompt=;

Написано longform, работает так:

while [ -z $prompt ];
  do read -p "Continue (y/n)?" choice;
  case "$choice" in
    y|Y ) prompt=true; break;;
    n|N ) exit 0;;
  esac;
done;
prompt=;
1 голос
/ 20 мая 2018

В ответ на других:

Вам не нужно указывать регистр в BASH4, просто используйте «,,», чтобы сделать переменную строчными Также мне очень не нравится помещать код внутри блока чтения, получать результат и иметь дело с ним вне IMO блока чтения. Также добавьте «q» для выхода из IMO. И наконец, почему введите «да», просто используйте -n1 и нажмите клавишу y.

Пример: пользователь может нажать y / n, а также q, чтобы просто выйти.

ans=''
while true; do
    read -p "So is MikeQ the greatest or what (y/n/q) ?" -n1 ans
    case ${ans,,} in
        y|n|q) break;;
        *) echo "Answer y for yes / n for no  or q for quit.";;
    esac
done

echo -e "\nAnswer = $ans"

if [[ "${ans,,}" == "q" ]] ; then
        echo "OK Quitting, we will assume that he is"
        exit 0
fi

if [[ "${ans,,}" == "y" ]] ; then
        echo "MikeQ is the greatest!!"
else
        echo "No? MikeQ is not the greatest?"
fi
1 голос
/ 14 июля 2017

Да / Нет / Отмена

Функция

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=''

  echo -n "> $message (Yes/No/Cancel) " >&2

  while [ -z "$result" ] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result='Y' ;;
      n|N ) result='N' ;;
      c|C ) result='C' ;;
    esac
  done

  echo $result
}

Использование

case $(@confirm 'Confirm?') in
  Y ) echo "Yes" ;;
  N ) echo "No" ;;
  C ) echo "Cancel" ;;
esac

Подтвердить с чистым пользовательским вводом

Функция

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=3

  echo -n "> $message (y/n) " >&2

  while [[ $result -gt 1 ]] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result=0 ;;
      n|N ) result=1 ;;
    esac
  done

  return $result
}

Использование

if @confirm 'Confirm?' ; then
  echo "Yes"
else
  echo "No"
fi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...