GNU/Linux >> Znalost Linux >  >> Linux

Jak mohu požádat o zadání Ano/Ne/Zrušit ve skriptu prostředí Linux?

Minimálně pět odpovědí na jednu obecnou otázku.

V závislosti na

  • Vyhovuje posix:může fungovat na špatných systémech s obecnými prostředími shellu
  • specifické pro bash:pomocí takzvaných bashismů

a pokud chcete

  • jednoduchá „v řadě“ otázka/odpověď (obecná řešení)
  • pěkně formátovaná rozhraní, jako ncurses nebo více grafických pomocí libgtk nebo libqt...
  • použijte výkonnou funkci readline historie

1. Obecná řešení POSIX

Můžete použít read za ním následuje if ... then ... else :

printf 'Is this a good question (y/n)? '
read answer
# if echo "$answer" | grep -iq "^y" ;then
if [ "$answer" != "${answer#[Yy]}" ] ;then # this grammar (the #[] operator) means that the variable $answer where any Y or y in 1st position will be dropped if they exist.
    echo Yes
else
    echo No
fi

(Díky komentáři Adama Katze:Výše ​​uvedený test byl nahrazen testem, který je přenosnější a vyhýbá se jedné vidlici:)

POSIX, ale funkce s jedním klíčem

Pokud ale nechcete, aby uživatel musel stisknout Return , můžete napsat:

(Upraveno: Jak @JonathanLeffler správně navrhuje, šetřím Konfigurace stty by mohla být lepší, než je prostě nutit k příčetnosti .)

printf '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

Poznámka: Toto bylo testováno pod sh, bash, ksh, dash a busybox!

Totéž, ale čeká se explicitně na y nebo n :

#/bin/sh
printf '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

Používání vyhrazených nástrojů

Existuje mnoho nástrojů, které byly vytvořeny pomocí libncurses , libgtk , libqt nebo jiné grafické knihovny. Například pomocí whiptail :

if whiptail --yesno "Is this a good question" 20 60 ;then
    echo Yes
else
    echo No
fi

V závislosti na vašem systému může být nutné nahradit whiptail pomocí jiného podobného nástroje:

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

kde 20 je výška dialogového okna v počtu řádků a 60 je šířka dialogového okna. Všechny tyto nástroje mají téměř stejné syntaxe.

DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...

2. Specifická řešení Bash

Základní v řadě metoda

read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
    y|Y )
        echo Yes
    ;;
    * )
        echo No
    ;;
esac

Dávám přednost použití case takže jsem mohl dokonce testovat na yes | ja | si | oui v případě potřeby...

v řadě pomocí jednoho klíče funkce

Pod bash můžeme zadat délku zamýšleného vstupu pro read příkaz:

read -n 1 -p "Is this a good question (y/n)? " answer

Pod bash read příkaz přijímá časový limit parametr, který by mohl být užitečný.

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

3. Několik triků pro vyhrazené nástroje

Sofistikovanější dialogová okna nad rámec jednoduchých yes - no účely:

dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe

Ukazatel průběhu:

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
) 

Malá ukázka:

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

Více vzorků? Podívejte se na Použití whiptailu k výběru zařízení USB a volič vyměnitelného úložiště USB:USBKeyChooser

5. Použití historie readline

Příklad:

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

Tím se vytvoří soubor .myscript.history ve vašem $HOME adresář, než byste mohli použít příkazy historie readline, jako Nahoru , Dolů , Ctrl +r a další.


Nejjednodušší a nejrozšířenější metoda pro získání uživatelského vstupu do příkazového řádku je read příkaz. Nejlepší způsob, jak ilustrovat jeho použití, je jednoduchá ukázka:

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

Další metodou, na kterou poukázal Steven Huwig, je Bashova select příkaz. Zde je stejný příklad s použitím 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

S select nemusíte vstup dezinfikovat – zobrazí dostupné možnosti a vy zadáte číslo odpovídající vašemu výběru. Také se automaticky zacyklí, takže není potřeba while true smyčka, aby to zkusil znovu, pokud dají neplatný vstup.

Léa Gris také ve své odpovědi předvedla způsob, jak učinit jazyk žádosti agnostickým. Úprava mého prvního příkladu pro lepší obsluhu více jazyků by mohla vypadat takto:

set -- $(locale LC_MESSAGES)
yesexpr="$1"; noexpr="$2"; yesword="$3"; noword="$4"

while true; do
    read -p "Install (${yesword} / ${noword})? " yn
    if [[ "$yn" =~ $yesexpr ]]; then make install; exit; fi
    if [[ "$yn" =~ $noexpr ]]; then exit; fi
    echo "Answer ${yesword} / ${noword}."
done

Je zřejmé, že zde zůstávají nepřeložené další komunikační řetězce (Install, Answer), které by bylo třeba řešit v úplnějším překladu, ale i částečný překlad by v mnoha případech pomohl.

Nakonec se prosím podívejte na skvělou odpověď F. Hauriho.


echo "Please enter some input: "
read input_variable
echo "You entered: $input_variable"

Linux
  1. Jak porovnávat čísla a řetězce ve skriptu Linux Shell

  2. Jak připojit data do vyrovnávací paměti ve skriptu Shell?

  3. Jak nainstaluji/vytvořím vlastní výzvu pro rybí skořápku?

  1. Jak předvánočně upravit váš linuxový terminál a Shell

  2. Znovu spustit skript, pokud je vstup Ano?

  3. Formát data a času pro skript nebo proměnnou prostředí Linux

  1. Skrytí uživatelského vstupu na terminálu ve skriptu Linux

  2. Jak hledat soubory pomocí regulárního výrazu ve skriptu linuxového shellu

  3. Jak napíšu odpověď ano pro instalaci programů?