Я хочу приостановить ввод в сценарии оболочки и предложить пользователю выбор.
Стандартный Yes
, No
или Cancel
типа вопрос.
Как мне сделать это в типичной командной строке?
read
команду для запроса
Я хочу приостановить ввод в сценарии оболочки и предложить пользователю выбор.
Стандартный Yes
, No
или Cancel
типа вопрос.
Как мне сделать это в типичной командной строке?
read
команду для запроса
Ответы:
Самым простым и наиболее доступным способом получения пользовательского ввода в командной строке является read
команда. Лучший способ проиллюстрировать его использование - это простая демонстрация:
while true; do
read -p "Do you wish to install this program?" yn
case $yn in
[Yy]* ) make install; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
Другой метод, указал на Стивене Huwig , является в Bash select
команды. Вот тот же пример с использованием select
:
echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
case $yn in
Yes ) make install; break;;
No ) exit;;
esac
done
При этом select
вам не нужно очищать ввод - он отображает доступные варианты, и вы вводите число, соответствующее вашему выбору. Он также зацикливается автоматически, поэтому нет необходимости while true
повторять цикл, если они дают неверный ввод.
Кроме того, Леа Гри продемонстрировала способ сделать язык запроса независимым в своем ответе . Адаптация моего первого примера для лучшего обслуживания нескольких языков может выглядеть следующим образом:
set -- $(locale LC_MESSAGES)
yesptrn="$1"; noptrn="$2"; yesword="$3"; noword="$4"
while true; do
read -p "Install (${yesword} / ${noword})? " yn
case $yn in
${yesptrn##^} ) make install; break;;
${noptrn##^} ) exit;;
* ) echo "Answer ${yesword} / ${noword}.";;
esac
done
Очевидно, что другие коммуникационные строки здесь остаются непереведенными (Install, Answer), которые должны быть учтены в более законченном переводе, но даже частичный перевод был бы полезен во многих случаях.
Наконец, пожалуйста , проверьте отличный ответ на Ф. Хаури .
exit
чтобы break
сохранить от не закрывая вкладку , когда я выбрал «нет».
break
в, select
если нет петли?
В зависимости от
и если вы хотите
Вы можете использовать read
команду, а затем if ... then ... else
:
echo -n "Is this a good question (y/n)? "
read answer
# if echo "$answer" | grep -iq "^y" ;then
if [ "$answer" != "${answer#[Yy]}" ] ;then
echo Yes
else
echo No
fi
(Благодаря комментарию Адама Каца : заменил приведенный выше тест на более переносимый и исключающий одну развилку :)
Но если вы не хотите, чтобы пользователь нажимал Return, вы можете написать:
( Отредактировано: как справедливо предположил @JonathanLeffler, сохранение конфигурации stty может быть лучше, чем просто принудительное их исправление .)
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Careful playing with stty
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
Примечание: это было проверено в соответствии сш, удар, КШ, тире а также BusyBox!
То же самое, но ожидая явно yили n:
#/bin/sh
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$( while ! head -c 1 | grep -i '[ny]' ;do true ;done )
stty $old_stty_cfg
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
Есть много инструментов , которые были построены с использованием libncurses
, libgtk
, libqt
или другие графические библиотеки. Например, используя whiptail
:
if whiptail --yesno "Is this a good question" 20 60 ;then
echo Yes
else
echo No
fi
В зависимости от вашей системы вам может потребоваться заменить whiptail
другой похожий инструмент:
dialog --yesno "Is this a good question" 20 60 && echo Yes
gdialog --yesno "Is this a good question" 20 60 && echo Yes
kdialog --yesno "Is this a good question" 20 60 && echo Yes
где 20
высота диалогового окна в количестве строк и 60
ширина диалогового окна. Эти инструменты имеют почти одинаковый синтаксис.
DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...
read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
y|Y )
echo Yes
;;
* )
echo No
;;
esac
Я предпочитаю использовать, case
чтобы я мог даже проверить, yes | ja | si | oui
если нужно ...
В bash мы можем указать длину предполагаемого ввода для read
команды:
read -n 1 -p "Is this a good question (y/n)? " answer
В bash read
команда принимает параметр времени ожидания , который может быть полезен.
read -t 3 -n 1 -p "Is this a good question (y/n)? " answer
[ -z "$answer" ] && answer="Yes" # if 'yes' have to be default choice
Более сложные диалоговые окна, помимо простых yes - no
целей:
dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe
Индикатор:
dialog --gauge "Filling the tank" 20 60 0 < <(
for i in {1..100};do
printf "XXX\n%d\n%(%a %b %T)T progress: %d\nXXX\n" $i -1 $i
sleep .033
done
)
Маленькая демка:
#!/bin/sh
while true ;do
[ -x "$(which ${DIALOG%% *})" ] || DIALOG=dialog
DIALOG=$($DIALOG --menu "Which tool for next run?" 20 60 12 2>&1 \
whiptail "dialog boxes from shell scripts" >/dev/tty \
dialog "dialog boxes from shell with ncurses" \
gdialog "dialog boxes from shell with Gtk" \
kdialog "dialog boxes from shell with Kde" ) || exit
clear;echo "Choosed: $DIALOG."
for i in `seq 1 100`;do
date +"`printf "XXX\n%d\n%%a %%b %%T progress: %d\nXXX\n" $i $i`"
sleep .0125
done | $DIALOG --gauge "Filling the tank" 20 60 0
$DIALOG --infobox "This is a simple info box\n\nNo action required" 20 60
sleep 3
if $DIALOG --yesno "Do you like this demo?" 20 60 ;then
AnsYesNo=Yes; else AnsYesNo=No; fi
AnsInput=$($DIALOG --inputbox "A text:" 20 60 "Text here..." 2>&1 >/dev/tty)
AnsPass=$($DIALOG --passwordbox "A secret:" 20 60 "First..." 2>&1 >/dev/tty)
$DIALOG --textbox /etc/motd 20 60
AnsCkLst=$($DIALOG --checklist "Check some..." 20 60 12 \
Correct "This demo is useful" off \
Fun "This demo is nice" off \
Strong "This demo is complex" on 2>&1 >/dev/tty)
AnsRadio=$($DIALOG --radiolist "I will:" 20 60 12 \
" -1" "Downgrade this answer" off \
" 0" "Not do anything" on \
" +1" "Upgrade this anser" off 2>&1 >/dev/tty)
out="Your answers:\nLike: $AnsYesNo\nInput: $AnsInput\nSecret: $AnsPass"
$DIALOG --msgbox "$out\nAttribs: $AnsCkLst\nNote: $AnsRadio" 20 60
done
Больше образца? Посмотрите Использование Whiptail для выбора USB-устройства и USB-накопителя: USBKeyChooser
Пример:
#!/bin/bash
set -i
HISTFILE=~/.myscript.history
history -c
history -r
myread() {
read -e -p '> ' $1
history -s ${!1}
}
trap 'history -a;exit' 0 1 2 3 6
while myread line;do
case ${line%% *} in
exit ) break ;;
* ) echo "Doing something with '$line'" ;;
esac
done
Это создаст файл .myscript.history
в вашем $HOME
каталоге, чем вы могли бы использовать команды истории Readline, как и Up, Down, Ctrl+ rи другие.
stty
обеспечивает -g
возможность для использования: old_stty=$(stty -g); stty raw -echo; …; stty "$old_stty"
. Это восстанавливает настройку в точности так, как они были найдены, которая может совпадать или не совпадать с stty -sane
.
case
для POSIX, так и для bash (используйте подстановочный знак вместо подстроки bash:) case $answer in; [Yy]* ) echo Yes ;;
, но я предпочитаю вместо этого использовать условный оператор, отдавая предпочтение [ "$answer" != "${answer#[Yy]}" ]
вашему echo "$answer" | grep -iq ^y
. Он более переносим (некоторые не-GNU greps не реализуются -q
правильно) и не имеет системного вызова. ${answer#[Yy]}
использует расширение параметра, чтобы удалить Y
или y
из начала $answer
, вызывая неравенство, когда либо присутствует. Это работает в любой оболочке POSIX (dash, ksh, bash, zsh, busybox и т. Д.).
echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"
Вы можете использовать встроенную команду чтения ; Используйте -p
опцию, чтобы ответить пользователю с вопросом.
Начиная с BASH4, теперь вы можете использовать, -i
чтобы предложить ответ:
read -e -p "Enter the path to the file: " -i "/usr/local/etc/" FILEPATH
echo $FILEPATH
(Но не забудьте использовать опцию «readline», -e
чтобы разрешить редактирование строки с помощью клавиш со стрелками)
Если вам нужна логика «да / нет», вы можете сделать что-то вроде этого:
read -e -p "
List the content of your home dir ? [Y/n] " YN
[[ $YN == "y" || $YN == "Y" || $YN == "" ]] && ls -la ~/
FILEPATH
это имя переменной, которое вы выбрали, и задается в ответе на командную строку. Так что если бы вы запустили vlc "$FILEPATH"
, например, vlc
открыли бы этот файл.
-e
во втором примере (просто да / нет)?
-e -p
вместо -ep
?
-e
флажка / опции вы можете (в зависимости от реализации) не иметь возможности набрать «y», а затем передумать и заменить его на «n» (или что-нибудь еще в этом отношении); При документировании команды перечисление параметров по отдельности лучше для удобства чтения / ясности, среди прочих причин.
Bash выбрал для этой цели.
select result in Yes No Cancel
do
echo $result
done
exit
внутренность :)
Ctrl-D
Но, конечно, для реального кода, использующего его, потребуется разрыв или выход в теле.)
exit
выйдет из сценария все вместе, break
выйдет только из цикла, в котором вы находитесь (если вы находитесь в цикле while
или case
)
Вот что я собрал:
#!/bin/sh
promptyn () {
while true; do
read -p "$1 " yn
case $yn in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) echo "Please answer yes or no.";;
esac
done
}
if promptyn "is the sky blue?"; then
echo "yes"
else
echo "no"
fi
Я новичок, поэтому возьмите это с крошкой соли, но, похоже, это сработает.
case $yn in
на, case ${yn:-$2} in
то вы можете использовать второй аргумент в качестве значения по умолчанию, Y или N.
case $yn
чтобы case "${yn:-Y}"
иметь да по умолчанию
inquire () {
echo -n "$1 [y/n]? "
read answer
finish="-1"
while [ "$finish" = '-1' ]
do
finish="1"
if [ "$answer" = '' ];
then
answer=""
else
case $answer in
y | Y | yes | YES ) answer="y";;
n | N | no | NO ) answer="n";;
*) finish="-1";
echo -n 'Invalid response -- please reenter:';
read answer;;
esac
fi
done
}
... other stuff
inquire "Install now?"
...
do_xxxx=y # In batch mode => Default is Yes
[[ -t 0 ]] && # If TTY => Prompt the question
read -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx # Store the answer in $do_xxxx
if [[ $do_xxxx =~ ^(y|Y|)$ ]] # Do if 'y' or 'Y' or empty
then
xxxx
fi
[[ -t 0 ]] && read ...
=> Команда вызова read
если TTYread -n 1
=> Ждать одного символа$'\e[1;32m ... \e[0m '
=> Печать зеленым цветом[[ $do_xxxx =~ ^(y|Y|)$ ]]
=> Bash регулярное выражениеdo_xxxx=y
[[ -t 0 ]] && { # Timeout 5 seconds (read -t 5)
read -t 5 -n 1 -p $'\e[1;32m
Do xxxx? (Y/n)\e[0m ' do_xxxx || # read 'fails' on timeout
do_xxxx=n ; } # Timeout => answer No
if [[ $do_xxxx =~ ^(y|Y|)$ ]]
then
xxxx
fi
Самый простой способ добиться этого с наименьшим количеством строк заключается в следующем:
read -p "<Your Friendly Message here> : y/n/cancel" CONDITION;
if [ "$CONDITION" == "y" ]; then
# do something here!
fi
Это if
просто пример: вам решать, как обращаться с этой переменной.
Используйте read
команду:
echo Would you like to install? "(Y or N)"
read x
# now check if $x is "y"
if [ "$x" = "y" ]; then
# do something here!
fi
а затем все остальные вещи, которые вам нужны
Это решение читает один символ и вызывает функцию с ответом «да».
read -p "Are you sure? (y/n) " -n 1
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
do_something
fi
echo
чтобы убедиться в этом.
Чтобы получить красивое поле ввода, похожее на ncurses, используйте командный диалог :
#!/bin/bash
if (dialog --title "Message" --yesno "Want to do something risky?" 6 25)
# message box will have the size 25x6 characters
then
echo "Let's do something risky"
# do something risky
else
echo "Let's stay boring"
fi
Диалоговый пакет устанавливается по умолчанию как минимум с SUSE Linux. Похоже:
read -e -p "Enter your choice: " choice
-e
Опция позволяет пользователю редактировать ввод с помощью клавиш со стрелками.
Если вы хотите использовать предложение в качестве входных данных:
read -e -i "yes" -p "Enter your choice: " choice
-i
опция печатает суггестивный ввод
-e
-i
не работай в sh (оболочка Bourne), но вопрос специально помечен как bash ..
Вы можете использовать значение REPLY
по умолчанию для a read
, преобразовать в нижний регистр и сравнить с набором переменных с выражением.
Сценарий также поддерживает ja
/ si
/oui
read -rp "Do you want a demo? [y/n/c] "
[[ ${REPLY,,} =~ ^(c|cancel)$ ]] && { echo "Selected Cancel"; exit 1; }
if [[ ${REPLY,,} =~ ^(y|yes|j|ja|s|si|o|oui)$ ]]; then
echo "Positive"
fi
Можно обрабатывать с учетом локали «выбор да / нет» в оболочке POSIX; используя записи LC_MESSAGES
категории локали, witch предоставляет готовые шаблоны RegEx для соответствия входным данным и строки для локализованного Да Нет.
#!/usr/bin/env sh
# Getting LC_MESSAGES values into variables
# shellcheck disable=SC2046 # Intended IFS splitting
IFS='
' set -- $(locale LC_MESSAGES)
yesexpr="$1"
noexpr="$2"
yesstr="$3"
nostr="$4"
messages_codeset="$5" # unused here, but kept as documentation
# Display Yes / No ? prompt into locale
echo "$yesstr / $nostr ?"
# Read answer
read -r yn
# Test answer
case "$yn" in
# match only work with the character class from the expression
${yesexpr##^}) echo "answer $yesstr" ;;
${noexpr##^}) echo "answer $nostr" ;;
esac
РЕДАКТИРОВАТЬ: Как @Urhixidur отметил в своем комментарии :
К сожалению, POSIX указывает только первые два (yesexpr и noexpr). В Ubuntu 16 yesstr и nostr пусты.
См .: https://www.ee.ryerson.ca/~courses/ele709/susv4/xrat/V4_xbd_chap07.html#tag_21_07_03_06.
LC_MESSAGES
yesstr
Иnostr
локал ключевые слова иYESSTR
иNOSTR
langinfo элементов ранее были использованы для пользовательского матча позитивных и негативных ответов. В POSIX.1-2008, темyesexpr
,noexpr
,YESEXPR
, иNOEXPR
расширенные регулярные выражения заменили их. Приложения должны использовать общие средства обмена сообщениями на основе локали для выдачи сообщений с подсказками, которые содержат примеры желаемых ответов.
В качестве альтернативы, используя локализацию Bash:
#!/usr/bin/env bash
IFS=$'\n' read -r -d '' yesexpr noexpr _ < <(locale LC_MESSAGES)
printf -v yes_or_no_regex "(%s)|(%s)" "$yesexpr" "$noexpr"
printf -v prompt $"Please answer Yes (%s) or No (%s): " "$yesexpr" "$noexpr"
declare -- answer=;
until [[ "$answer" =~ $yes_or_no_regex ]]; do
read -rp "$prompt" answer
done
if [[ -n "${BASH_REMATCH[1]}" ]]; then
echo $"You answered: Yes"
else
echo $"No, was your answer."
fi
Ответ сопоставляется с использованием регулярных выражений, предусмотренных в локали.
Чтобы перевести остальные сообщения, используйте bash --dump-po-strings scriptname
для вывода строки po для локализации:
#: scriptname:8
msgid "Please answer Yes (%s) or No (%s): "
msgstr ""
#: scriptname:17
msgid "You answered: Yes"
msgstr ""
#: scriptname:19
msgid "No, was your answer."
msgstr ""
yesexpr
и noexpr
в среде оболочки, является использование его в согласовании конкретных RegEx Bashif [[ "$yn" =~ $yesexpr ]]; then echo $"Answered yes"; else echo $"Answered no"; fi
Вот более длинный, но многократно используемый и модульный подход:
0
= да и 1
= нетzsh
и bash
.Обратите внимание, что N
заглавная. Здесь нажимается ввод, принимая значение по умолчанию:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?
Также обратите внимание, что это [y/N]?
было автоматически добавлено. По умолчанию «нет» принимается, поэтому ничего не отображается.
Повторяйте запрос, пока не получите правильный ответ:
$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *
Обратите внимание, что Y
заглавная:
$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *
Выше я просто нажал клавишу ввода, поэтому команда запустилась.
y
илиn
$ get_yes_keypress "Here you cannot press enter. Do you like this [y/n]? "
Here you cannot press enter. Do you like this [y/n]? k
Here you cannot press enter. Do you like this [y/n]?
Here you cannot press enter. Do you like this [y/n]? n
$ echo $?
1
Здесь 1
или ложь была возвращена. Обратите внимание, что с помощью этой функции более низкого уровня вам нужно будет предоставить собственное [y/n]?
приглашение.
# Read a single char from /dev/tty, prompting with "$*"
# Note: pressing enter will return a null string. Perhaps a version terminated with X and then remove it in caller?
# See https://unix.stackexchange.com/a/367880/143394 for dealing with multi-byte, etc.
function get_keypress {
local REPLY IFS=
>/dev/tty printf '%s' "$*"
[[ $ZSH_VERSION ]] && read -rk1 # Use -u0 to read from STDIN
# See https://unix.stackexchange.com/q/383197/143394 regarding '\n' -> ''
[[ $BASH_VERSION ]] && </dev/tty read -rn1
printf '%s' "$REPLY"
}
# Get a y/n from the user, return yes=0, no=1 enter=$2
# Prompt using $1.
# If set, return $2 on pressing enter, useful for cancel or defualting
function get_yes_keypress {
local prompt="${1:-Are you sure [y/n]? }"
local enter_return=$2
local REPLY
# [[ ! $prompt ]] && prompt="[y/n]? "
while REPLY=$(get_keypress "$prompt"); do
[[ $REPLY ]] && printf '\n' # $REPLY blank if user presses enter
case "$REPLY" in
Y|y) return 0;;
N|n) return 1;;
'') [[ $enter_return ]] && return "$enter_return"
esac
done
}
# Credit: http://unix.stackexchange.com/a/14444/143394
# Prompt to confirm, defaulting to NO on <enter>
# Usage: confirm "Dangerous. Are you sure?" && rm *
function confirm {
local prompt="${*:-Are you sure} [y/N]? "
get_yes_keypress "$prompt" 1
}
# Prompt to confirm, defaulting to YES on <enter>
function confirm_yes {
local prompt="${*:-Are you sure} [Y/n]? "
get_yes_keypress "$prompt" 0
}
Show dangerous command [y/N]? [y/n]?
иShow dangerous command [Y/n]? [y/n]?
Извините за публикацию на такой старый пост. Несколько недель назад я столкнулся с подобной проблемой, в моем случае мне нужно было решение, которое также работало в онлайн-установочном скрипте, например:curl -Ss https://raw.github.com/_____/installer.sh | bash
Использование read yesno < /dev/tty
отлично работает для меня:
echo -n "These files will be uploaded. Is this ok? (y/n) "
read yesno < /dev/tty
if [ "x$yesno" = "xy" ];then
# Yes
else
# No
fi
Надеюсь, это кому-нибудь поможет.
tty
ввод, как вы это сделали, также сработала бы для вас, а также получила бы цикл при неправильном вводе (представьте несколько символов в буфере; ваш метод заставит пользователя всегда выбирать нет).
Я заметил, что никто не опубликовал ответ, показывающий многострочное эхо-меню для такого простого пользовательского ввода, так что вот мое мнение:
#!/bin/bash
function ask_user() {
echo -e "
#~~~~~~~~~~~~#
| 1.) Yes |
| 2.) No |
| 3.) Quit |
#~~~~~~~~~~~~#\n"
read -e -p "Select 1: " choice
if [ "$choice" == "1" ]; then
do_something
elif [ "$choice" == "2" ]; then
do_something_else
elif [ "$choice" == "3" ]; then
clear && exit 0
else
echo "Please select 1, 2, or 3." && sleep 3
clear && ask_user
fi
}
ask_user
Этот метод был опубликован в надежде, что кто-то найдет его полезным и экономящим время.
Вариант с множественным выбором:
ask () { # $1=question $2=options
# set REPLY
# options: x=..|y=..
while $(true); do
printf '%s [%s] ' "$1" "$2"
stty cbreak
REPLY=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
stty -cbreak
test "$REPLY" != "$(printf '\n')" && printf '\n'
(
IFS='|'
for o in $2; do
if [ "$REPLY" = "${o%%=*}" ]; then
printf '\n'
break
fi
done
) | grep ^ > /dev/null && return
done
}
Пример:
$ ask 'continue?' 'y=yes|n=no|m=maybe'
continue? [y=yes|n=no|m=maybe] g
continue? [y=yes|n=no|m=maybe] k
continue? [y=yes|n=no|m=maybe] y
$
Он будет установлен REPLY
на y
(внутри скрипта).
Я предлагаю вам использовать диалог ...
Ученик Linux: улучшение сценариев оболочки Bash с помощью диалогового окна
Команда dialog позволяет использовать оконные блоки в сценариях оболочки, чтобы сделать их использование более интерактивным.
он прост и удобен в использовании, также есть версия gnome под названием gdialog, которая принимает те же параметры, но показывает стиль GUI на X.
Вдохновленный ответами @Mark и @Myrddin, я создал эту функцию для универсального приглашения
uniprompt(){
while true; do
echo -e "$1\c"
read opt
array=($2)
case "${array[@]}" in *"$opt"*) eval "$3=$opt";return 0;; esac
echo -e "$opt is not a correct value\n"
done
}
используйте это так:
unipromtp "Select an option: (a)-Do one (x)->Do two (f)->Do three : " "a x f" selection
echo "$selection"
более общим будет:
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
}
Один простой способ сделать это с помощью xargs -p
или GNU parallel --interactive
.
Мне нравится поведение xargs немного лучше, потому что оно выполняет каждую команду сразу после приглашения, как и другие интерактивные команды unix, вместо того, чтобы собирать дачи для выполнения в конце. (Вы можете Ctrl-C после того, как вы пройдете через те, которые вы хотели.)
например,
echo *.xml | xargs -p -n 1 -J {} mv {} backup/
xargs --interactive
ограничено да или нет. Пока это все, что вам нужно, этого может быть достаточно, но мой оригинальный вопрос привел пример с тремя возможными результатами. Мне действительно нравится, что это поток, хотя; многие распространенные сценарии извлекут выгоду из его способности быть переданным по трубопроводу.
В качестве друга однострочной команды я использовал следующее:
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=;
Я использовал это case
утверждение пару раз в таком сценарии, и использование статистики случая - хороший способ сделать это. while
Петля, что ecapsulates в 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
#!/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
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!'
yn(){ read -s -n 1 -p '[y/n]'; test "$REPLY" = "y" ; } yn && echo success || echo failure
В ответ на других:
Вам не нужно указывать регистр в 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
В большинстве случаев в таких сценариях необходимо продолжать выполнение сценария до тех пор, пока пользователь не продолжит вводить «да», и останавливать его нужно только тогда, когда пользователь вводит «нет». Приведенный ниже фрагмент поможет вам достичь этого!
#!/bin/bash
input="yes"
while [ "$input" == "yes" ]
do
echo "execute script functionality here..!!"
echo "Do you want to continue (yes/no)?"
read input
done
[yn]
опцию, то заглавная будет по умолчанию, то есть по[Yn]
умолчанию «да», а по[yN]
умолчанию «нет». См. Ux.stackexchange.com/a/40445/43532