W Bash, jak dodać "Are you sure [Y / n]" do dowolnego polecenia lub aliasu?

W tym konkretnym przypadku chciałbym dodać potwierdzenie w Bash dla

Are you sure? [Y/n]

Dla Mercuriala hg push ssh://[email protected]//somepath/morepath, który jest w rzeczywistości aliasem. Czy istnieje standardowe polecenie, które można dodać do aliasu, aby to osiągnąć?

Powodem jest to, że hg push i hg out mogą brzmieć podobnie i czasami, gdy chcę hgoutrepo, mogę przypadkowo wpisać hgpushrepo (oba są aliasami).

Update: jeśli może to być coś w rodzaju wbudowanego polecenia z innym poleceniem, np.: {[6] }to byłoby świetnie... po prostu polecenie, które może poprosić o yes lub no i kontynuować z resztą if yes.

Author: 太極者無極而生, 2010-07-12

16 answers

Są to bardziej zwarte i wszechstronne formy odpowiedź Hamisha . Obsługują dowolną kombinację wielkich i małych liter:

read -r -p "Are you sure? [y/N] " response
case "$response" in
    [yY][eE][sS]|[yY]) 
        do_something
        ;;
    *)
        do_something_else
        ;;
esac

Lub, dla Bash > = Wersja 3.2:

read -r -p "Are you sure? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
    do_something
else
    do_something_else
fi

Uwaga: Jeśli $response jest pustym łańcuchem znaków, spowoduje to błąd. Aby naprawić, wystarczy dodać cudzysłów: "$response". – Zawsze używaj podwójnych cudzysłowów w zmiennych zawierających ciągi znaków (np.: preferuj "$@" zamiast $@).

Lub, Bash 4.x:

read -r -p "Are you sure? [y/N] " response
response=${response,,}    # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
...

Edit:

W odpowiedzi na Twój edit, oto jak stworzyłbyś i użyłbyś polecenia confirm na podstawie pierwszej wersji mojej odpowiedzi (działałoby to podobnie z pozostałymi dwoma):

confirm() {
    # call with a prompt string or use a default
    read -r -p "${1:-Are you sure? [y/N]} " response
    case "$response" in
        [yY][eE][sS]|[yY]) 
            true
            ;;
        *)
            false
            ;;
    esac
}

Aby użyć tej funkcji:

confirm && hg push ssh://..

Lub

confirm "Would you really like to do a push?" && hg push ssh://..
 269
Author: Dennis Williamson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-19 13:29:29

Oto mniej więcej fragment, który chcesz. Pozwól, że dowiem się, jak przekazać argumenty.

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]
then
  # http://stackoverflow.com/questions/1537673/how-do-i-forward-parameters-to-other-command-in-bash-script
else
  exit 0
fi

Uważaj na yes | command name here :)

 19
Author: Hamish Grubijan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-12 20:04:12

Aby uniknąć jawnego sprawdzania tych wariantów 'yes', możesz użyć operatora wyrażenia regularnego bash '= ~ ' z wyrażeniem regularnym:

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ $prompt =~ [yY](es)* ]]
then
(etc...)

Sprawdza, czy dane wejściowe użytkownika zaczynają się od "y" lub "Y", a po nich następuje zero lub więcej "es".

 10
Author: user389850,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-12 20:33:23

Potwierdzenia można łatwo ominąć zwrotami karetki i uważam, że przydatne jest ciągłe pytanie o poprawne dane wejściowe.

Oto funkcja, która to ułatwi. "invalid input" pojawi się na czerwono, jeśli Y / N nie zostanie odebrane, a użytkownik zostanie ponownie poproszony.

prompt_confirm() {
  while true; do
    read -r -n 1 -p "${1:-Continue?} [y/n]: " REPLY
    case $REPLY in
      [yY]) echo ; return 0 ;;
      [nN]) echo ; return 1 ;;
      *) printf " \033[31m %s \n\033[0m" "invalid input"
    esac 
  done  
}

# example usage
prompt_confirm "Overwrite File?" || exit 0

Możesz zmienić domyślny znak zachęty przekazując argument

 7
Author: briceburg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 04:00:25

To może być hack:

Jak w pytaniu W Unix / Bash, czy "xargs-p "jest dobrym sposobem na poproszenie o potwierdzenie przed uruchomieniem jakiejkolwiek komendy?

Możemy użyć xargs do wykonania zadania:

echo ssh://[email protected]//somepath/morepath | xargs -p hg push

Oczywiście będzie to ustawione jako alias, jak hgpushrepo

Przykład:

$ echo foo | xargs -p ls -l
ls -l foo?...y
-rw-r--r--  1 mikelee    staff  0 Nov 23 10:38 foo

$ echo foo | xargs -p ls -l
ls -l foo?...n

$
 4
Author: 太極者無極而生,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:51

Dodaj następujący plik do pliku/etc / bashrc. Skrypt ten dodaje rezydentną " funkcję "zamiast aliasu o nazwie"confirm".


function confirm( )
{
#alert the user what they are about to do.
echo "About to $@....";
#confirm with the user
read -r -p "Are you sure? [Y/n]" response
case "$response" in
    [yY][eE][sS]|[yY]) 
              #if yes, then execute the passed parameters
               "$@"
               ;;
    *)
              #Otherwise exit...
              echo "ciao..."
              exit
              ;;
esac
}
 3
Author: MattyV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 18:30:35
read -r -p "Are you sure? [Y/n]" response
  response=${response,,} # tolower
  if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
      your-action-here
  fi
 3
Author: SergioAraujo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 14:03:00

Oto moja wersja confirm, zmodyfikowana z wersji Jamesa:

function confirm() {
  local response msg="${1:-Are you sure} (y/[n])? "; shift
  read -r $* -p "$msg" response || echo
  case "$response" in
  [yY][eE][sS]|[yY]) return 0 ;;
  *) return 1 ;;
  esac
}

Te zmiany to:

  1. użyj local, aby zapobiec kolizji nazw zmiennych
  2. read Użyj $2 $3 ... do kontrolowania jego działania, więc możesz używać -n i -t
  3. jeśli read wyjdzie bezskutecznie, echo linia dla urody
  4. mój Git on Windows ma tylko bash-3.1 i nie ma true ani false, więc zamiast tego użyj return. Oczywiście jest to również zgodne z bash - 4.4 (obecną w Git Dla Windows).
  5. użyj stylu IPython " (y / [n])", aby wyraźnie wskazać, że "n" jest domyślne.
 2
Author: Dahan Gong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-26 06:19:33

Późno do gry, ale stworzyłem kolejny wariant confirm funkcji poprzednich odpowiedzi:

confirm ()
{
    read -r -p "$(echo $@) ? [y/N] " YESNO

    if [ "$YESNO" != "y" ]; then
        echo >&2 "Aborting"
        exit 1
    fi

    CMD="$1"
    shift

    while [ -n "$1" ]; do
        echo -en "$1\0"
        shift
    done | xargs -0 "$CMD" || exit $?
}

Aby go użyć:

confirm your_command

Cechy:

  • wypisuje Twoje polecenie jako część wiersza
  • przekazuje argumenty za pomocą ogranicznika NULL
  • zachowuje stan wyjścia polecenia

Błędy:

  • echo -en działa z bash ale może zawieść w Twojej powłoce
  • może się nie udać, jeśli argumenty przeszkadzają echo lub xargs
  • milion innych błędów, ponieważ skrypty powłoki są trudne
 1
Author: thomas.me,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-02 01:52:40

Try,

 #!/bin/bash
 pause ()
 {
 REPLY=Y
 while [ "$REPLY" == "Y" ] || [ "$REPLY" != "y" ]
 do
  echo -e "\t\tPress 'y' to continue\t\t\tPress 'n' to quit"
  read -n1 -s
      case "$REPLY" in
      "n")  exit                      ;;
      "N")  echo "case sensitive!!"   ;; 
      "y")  clear                     ;;
      "Y")  echo "case sensitive!!"   ;;
      * )  echo "$REPLY is Invalid Option"     ;;
 esac
 done
 }
 pause
 echo "Hi"
 1
Author: Ranjithkumar T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-05 09:15:30

Nie jest wymagane naciśnięcie klawisza enter

Oto dłuższe, ale wielokrotnego użytku i modułowe podejście:]}
  • zwraca 0=Tak i 1 = Nie
  • nie jest wymagane naciśnięcie klawisza enter - tylko jeden znak
  • można nacisnąć enter , aby zaakceptować domyślny wybór
  • Można wyłączyć domyślny wybór, aby wymusić wybór]}
  • Działa zarówno dla zsh jak i bash.

Domyślnie " nie " po naciśnięciu enter

Zauważ, że N jest pisana wielkimi literami. Tutaj wciśnięty jest enter, akceptując domyślne:

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]?

Zauważ również, że [y/N]? została automatycznie dołączona. Domyślne " nie " jest akceptowane, więc nic nie jest echem.

Re-prompt dopóki nie zostanie podana prawidłowa odpowiedź:

$ confirm "Show dangerous command" && echo "rm *"
Show dangerous command [y/N]? X
Show dangerous command [y/N]? y
rm *

Domyślnie " tak " po naciśnięciu enter

Zauważ, że Y jest pisane wielkimi literami:

$ confirm_yes "Show dangerous command" && echo "rm *"
Show dangerous command [Y/n]?
rm *

Powyżej, po prostu wcisnąłem enter, więc Komenda uruchomiła się.

No default on enter - require y or n

$ get_yes_keypress "Here you cannot press enter. Do you like this"
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

Tutaj, 1 lub false został zwrócony. Uwaga brak kapitalizacji w [y/n]?

Kod

# 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
}
 1
Author: Tom Hale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 06:50:26

To nie jest dokładnie "Prośba o tak lub nie", ale tylko hack: alias hg push ... nie do hgpushrepo, ale do hgpushrepoconfirmedpush i zanim będę mógł przeliterować całą sprawę, lewy mózg dokonał logicznego wyboru.

 0
Author: 太極者無極而生,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-13 21:36:53

Nie to samo, ale pomysł, który i tak działa.

#!/bin/bash  
i='y'  
while [ ${i:0:1} != n ]  
do  
    # Command(s)  
    read -p " Again? Y/n " i  
    [[ ${#i} -eq 0 ]] && i='y'  
done  

Wyjście:
Znowu? Y / n n
Znowu? Y / N Anything
Znowu? Y / n 7
Znowu? Y / n &
Znowu? Y / n nsijf
$

Teraz sprawdza tylko 1 znak $I read.

 0
Author: anonimous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-02 06:31:46

Poniższy kod łączy dwie rzeczy

  1. Shopt - s nocasematch, który zajmie się case niewrażliwe

  2. I jeśli warunek, który będzie akceptował oba dane wejściowe, albo przechodzisz Tak,Tak,Tak, y.

    Shopt-s nocasematch

    Jeżeli [[ sed-4.2.2.$LINE = ~(yes|y)$]]

    Then exit 0

    Fi

 0
Author: Shyam Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-30 14:21:43

Oto moje rozwiązanie, które za pomocą zlokalizowanych regex. Więc w języku niemieckim również "j" Dla " Ja " byłoby interpretowane jako tak.

Pierwszym argumentem jest pytanie, jeśli drugim argumentem jest "y", to tak będzie domyślną odpowiedzią, w przeciwnym razie nie będzie domyślną odpowiedzią. Zwracaną wartością jest 0, jeśli odpowiedź brzmi "tak" i 1, jeśli odpowiedź brzmi "nie".

function shure(){
    if [ $# -gt 1 ] && [[ "$2" =~ ^[yY]*$ ]] ; then
        arg="[Y/n]"
        reg=$(locale noexpr)
        default=(0 1)
    else
        arg="[y/N]"
        reg=$(locale yesexpr)
        default=(1 0)
    fi
    read -p "$1 ${arg}? : " answer
    [[ "$answer" =~ $reg ]] && return ${default[1]} || return ${default[0]}
}

Oto podstawowe użycie

# basic example default is no
shure "question message" && echo "answer yes" || echo "answer no"
# print "question message [y/N]? : "

# basic example default set to yes
shure "question message" y && echo "answer yes" || echo "answer no"
# print "question message [Y/n]? : "
 0
Author: David Boho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-09 09:20:14

To może być trochę za krótkie, ale dla mojego prywatnego użytku, to działa świetnie

read -n 1 -p "Push master upstream? [Y/n] " reply; 
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" != "n" ]; then
    git push upstream master
fi

read -n 1 odczytuje tylko jeden znak. Jeśli nie jest małą literą "n", zakłada się, że jest "Y".

(jeśli chodzi o prawdziwe pytanie: stwórz skrypt bash i zmień alias, aby wskazywał na ten skrypt zamiast tego, co było wskazywane wcześniej)

 0
Author: commonpike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 14:14:23