it-swarm.com.de

Wie füge ich in Bash "Sind Sie sicher, dass [J / n]" zu einem Befehl oder Alias ​​hinzu?

In diesem speziellen Fall möchte ich eine Bestätigung in Bash für hinzufügen

Bist du sicher? [J/n] 

für Mercurial's hg Push ssh://[email protected]//somepath/morepath, was eigentlich ein Alias ​​ist. Gibt es einen Standardbefehl, der zum Alias ​​hinzugefügt werden kann, um diesen zu erreichen?

Der Grund ist, dass hg Push und hg out kann sich ähnlich anhören und manchmal, wenn ich hgoutrepo möchte, kann ich versehentlich hgpushrepo eingeben (beide sind Aliase).

pdate: wenn es so etwas wie ein eingebauter Befehl mit einem anderen Befehl sein kann, wie: confirm && hg Push ssh://... das wäre großartig ... nur ein Befehl, der nach einem yes oder no fragen und mit dem Rest fortfahren kann, wenn yes.

205

Dies sind kompaktere und vielseitigere Formen von Hamishs Antwort . Sie verarbeiten jede Mischung aus Groß- und Kleinbuchstaben:

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

Oder für Bash> = Version 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

Hinweis: Wenn $response ist eine leere Zeichenkette, es wird ein Fehler ausgegeben. Um dies zu beheben, fügen Sie einfach Anführungszeichen hinzu: "$response". - Verwenden Sie in Variablen, die Zeichenfolgen enthalten, immer doppelte Anführungszeichen (z. B. verwenden Sie lieber "[email protected]" stattdessen [email protected]).

Oder Bash 4.x:

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

Bearbeiten:

Als Reaktion auf Ihre Bearbeitung erstellen und verwenden Sie einen confirm -Befehl, der auf der ersten Version in meiner Antwort basiert (dies würde ähnlich wie bei den anderen beiden funktionieren):

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
}

So verwenden Sie diese Funktion:

confirm && hg Push ssh://..

oder

confirm "Would you really like to do a push?" && hg Push ssh://..
299

Hier ist ungefähr ein Ausschnitt, den Sie nicht werden. Lassen Sie mich herausfinden, wie ich die Argumente weiterleiten kann.

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

Achten Sie auf yes | command name here :)

19
Hamish Grubijan

Bestätigungen werden bei Wagenrückläufen leicht umgangen, und ich finde es nützlich, ständig nach gültigen Eingaben zu fragen.

Hier ist eine Funktion, um dies zu vereinfachen. "ungültige Eingabe" wird rot angezeigt, wenn Y | N nicht empfangen wird, und der Benutzer wird erneut aufgefordert.

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

Sie können die Standard-Eingabeaufforderung ändern, indem Sie ein Argument übergeben

11
briceburg

Um nicht explizit nach diesen Varianten von 'yes' zu suchen, können Sie den regulären Ausdrucksoperator '= ~' für einen regulären Ausdruck verwenden:

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

Damit wird geprüft, ob die Benutzereingabe mit 'y' oder 'Y' beginnt und von null oder mehr 'es' gefolgt wird.

11
user389850

Dies kann ein Hack sein:

wie in Frage In Unix/Bash ist "xargs -p" eine gute Möglichkeit, vor dem Ausführen eines Befehls zur Bestätigung aufzufordern?

wir können xargs benutzen, um die Arbeit zu erledigen:

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

natürlich wird dies als Alias ​​gesetzt, wie zB hgpushrepo

Beispiel:

$ 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

$
read -r -p "Are you sure? [Y/n]" response
  response=${response,,} # tolower
  if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
      your-action-here
  fi
3
SergioAraujo

Fügen Sie Folgendes zu Ihrer/etc/bashrc-Datei hinzu. Dieses Skript fügt eine residente "Funktion" anstelle eines Alias ​​"confirm" hinzu.


function confirm( )
{
#alert the user what they are about to do.
echo "About to [email protected]";
#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
               "[email protected]"
               ;;
    *)
              #Otherwise exit...
              echo "ciao..."
              exit
              ;;
esac
}
3
MattyV

Nun, hier ist meine Version von confirm, modifiziert von der von James:

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
}

Diese Änderungen sind:

  1. verwenden Sie local, um zu verhindern, dass Variablennamen kollidieren
  2. read benutze $2 $3 ... um die Aktion zu steuern, kannst du -n und -t
  3. wenn read nicht erfolgreich beendet wird, echo ein Zeilenvorschub für Schönheit
  4. mein Git on Windows hat nur bash-3.1 und hat kein true oder false, verwenden Sie stattdessen return. Dies ist natürlich auch kompatibel mit bash-4.4 (der aktuellen Version in Git für Windows).
  5. verwenden Sie "(y/[n])" im IPython-Stil, um deutlich zu machen, dass "n" die Standardeinstellung ist.
2
Dahan Gong

Spät zum Spiel, aber ich habe noch eine weitere Variante der confirm -Funktionen früherer Antworten erstellt:

confirm ()
{
    read -r -p "$(echo [email protected]) ? [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 $?
}

Um es zu benutzen:

confirm your_command

Eigenschaften:

  • druckt Ihren Befehl als Teil der Eingabeaufforderung
  • übergibt Argumente mithilfe des NULL-Trennzeichens
  • erhält den Beendigungsstatus Ihres Befehls

Bugs:

  • echo -en funktioniert mit bash, kann aber in Ihrer Shell fehlschlagen
  • kann fehlschlagen, wenn Argumente echo oder xargs stören
  • unzählige andere Fehler, da Shell-Skripte schwierig sind
1
thomas.me

Versuchen,

 #!/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
Ranjithkumar T

Kein Drücken der Eingabetaste erforderlich

Hier ist ein längerer, aber wiederverwendbarer und modularer Ansatz:

  • Kehrt zurück 0 = yes und 1 = nein
  • Kein Drücken der Eingabetaste erforderlich - nur ein einzelnes Zeichen
  • Kann drücken enter um die Standardauswahl zu akzeptieren
  • Kann die Standardauswahl deaktivieren, um eine Auswahl zu erzwingen
  • Funktioniert sowohl für zsh als auch für bash.

Standardmäßig "nein", wenn die Eingabetaste gedrückt wird

Beachten Sie, dass das N groß geschrieben ist. Hier wird die Eingabetaste gedrückt, wobei die Standardeinstellung übernommen wird:

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

Beachten Sie auch, dass [y/N]? wurde automatisch angehängt. Die Standardeinstellung "nein" wird akzeptiert, daher wird nichts zurückgemeldet.

Wiederholen Sie die Eingabeaufforderung, bis eine gültige Antwort vorliegt:

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

Standardmäßig "Ja", wenn die Eingabetaste gedrückt wird

Beachten Sie, dass das Y groß geschrieben wird:

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

Oben habe ich einfach die Eingabetaste gedrückt, sodass der Befehl ausgeführt wurde.

Kein Standard ein enter - erfordern y oder 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

Hier, 1 oder false wurde zurückgegeben. Beachten Sie keine Großschreibung in [y/n]?

Code

# 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
Tom Hale

Das mag ein bisschen zu kurz sein, aber für meinen privaten Gebrauch funktioniert es großartig

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

Das read -n 1 liest nur ein Zeichen. Sie müssen nicht die Eingabetaste drücken. Wenn es kein 'n' oder 'N' ist, wird angenommen, dass es ein 'Y' ist. Wenn Sie einfach die Eingabetaste drücken, bedeutet dies auch "Y".

(Was die eigentliche Frage betrifft: Mache das zu einem Bash-Skript und ändere deinen Alias ​​so, dass er auf dieses Skript zeigt, anstatt auf das, was vorher gezeigt wurde.)

1
commonpike

Hier ist meine Lösung, die lokalisierte reguläre Ausdrücke verwendet. So würde im Deutschen auch "j" für "Ja" als "ja" interpretiert.

Das erste Argument ist die Frage, ob das zweite Argument "y" ist, als die Standardantwort "yes", andernfalls ist "no" die Standardantwort. Der Rückgabewert ist 0, wenn die Antwort "Ja" war, und 1, wenn die Antwort "Nein" war.

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]}
}

Hier ist eine grundlegende Verwendung

# 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
David Boho

Der folgende Code kombiniert zwei Dinge

  1. shopt -s nocasematch, bei dem zwischen Groß- und Kleinschreibung unterschieden wird

  2. und wenn Bedingung, die beide Eingaben akzeptiert, entweder Sie ja, ja, JA, y übergeben.

    shopt -s nocasematch

    if [[sed-4.2.2. $ LINE = ~ (yes | y) $]]

    dann Ausfahrt 0

    fi

0
Shyam Gupta

Dies ist nicht gerade ein "Fragen nach Ja oder Nein", sondern nur ein Hack: Alias ​​der hg Push ... nicht zu hgpushrepo, sondern zu hgpushrepoconfirmedpush und bis ich das Ganze buchstabieren kann, hat die linke Gehirnhälfte eine logische Entscheidung getroffen.

Nicht dasselbe, aber die Idee funktioniert trotzdem.

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

Ausgabe:
Nochmal? J/N N
Nochmal? J/n Alles
Nochmal? J/N 7
Nochmal? J/N &
Nochmal? J/n nsijf
$

Prüft jetzt nur das 1. Zeichen von $ i.

0
anonimous