8 votes

Comment faire en sorte que le fichier bash donne un écho différent en fonction de l'entrée de l'utilisateur ?

Je suis assez novice en matière de Shell Shell, mais j'aimerais écrire un Shell basique où le fichier bash répercutera une ligne de texte différente en fonction de la saisie de l'utilisateur. Par exemple, si le Shell demande à l'utilisateur "Are you there ?" et que la saisie de l'utilisateur est "yes" ou "Yes", alors le Shell fera écho à quelque chose comme "hello !". Mais si la saisie de l'utilisateur est "non" ou "Non", le Shell ferait écho à quelque chose d'autre. Et enfin, si la saisie de l'utilisateur est autre chose que oui/oui ou non/non, le Shell ferait écho à "Veuillez répondre oui ou non". Voici ce que j'ai jusqu'à présent :

echo "Are you there?"  
read $input  

if [ $input == $yes ]; then  
    echo "Hello!"  
elif [ $input == $no ]]; then  
    echo "Are you sure?"  
else  
    echo "Please answer yes or no."  
fi  

Cependant, quelle que soit l'entrée, j'obtiens toujours la première réponse ("Bonjour !").

J'aimerais également intégrer la synthèse vocale (comme je l'ai fait avec d'autres projets de fichiers bash utilisant festival). Dans d'autres fichiers bash, je l'ai fait de cette façon :

echo "Hello!"  
echo "Hello!" | festival --tts

Y a-t-il un moyen d'incorporer cela dans l'invite si alors/oui non ci-dessus ? Merci d'avance, j'utilise ceci pour faire des fichiers bash simples et pour m'aider à apprendre.

14voto

Olorin Points 3248

Le problème principal est ici :

read $input

Dans bash, généralement, $foo est la valeur de la variable foo . Ici, vous ne voulez pas la valeur, mais le nom de la variable, donc il devrait être juste :

read input

De même, dans le if tests, $yes y $no devrait être juste yes y no puisque vous ne voulez que les chaînes de caractères yes y no là.

Vous pourriez utiliser un case ici, ce qui (IMHO) rend plus facile de faire des cas multiples basés sur l'entrée :

case $input in
[Yy]es)    # The first character can be Y or y, so both Yes and yes work
    echo "Hello!"  
    echo "Hello!" | festival --tts
    ;;
[Nn]o)     # no or No
    echo "Are you sure?"
    echo "Are you sure?" | festival --tts
    ;;
*)         # Anything else
    echo "Please answer yes or no."
    echo "Please answer yes or no." | festival --tts
    ;;
esac

Vous pourriez envelopper les deux echo et l'utilisation de festival dans une fonction pour éviter de se répéter :

textAndSpeech ()
{
    echo "$@"
    echo "$@" | festival --tts
}
case $input in
[Yy]es)    # The first character can be Y or y, so both Yes and yes work
    textAndSpeech "Hello!"  
    ;;
[Nn]o)     # no or No
    textAndSpeech "Are you sure?"
    ;;
*)         # Anything else
    textAndSpeech "Please answer yes or no."
    ;;
esac

Avec $input bash le remplace par sa valeur, qui n'est rien au départ, de sorte que la commande read la commande est lancée :

read 

Et read par défaut stocke l'entrée dans la variable REPLY . Donc vous pouvez, si vous voulez, éliminer le input et utiliser la variable $REPLY au lieu de $input .


Jetez également un coup d'œil à le site select déclaration dans Bash.

14voto

Sergiy Kolodyazhnyy Points 97292

TL;DR : corrigez les erreurs de syntaxe, assurez-vous que vous avez réellement des variables non vides dans le fichier [ et créer une fonction pour faire passer le test tee en festival .

Pour ce qui est de l'impression à l'écran et de la sortie vers l'extérieur, il n'y a pas de problème. festival Personnellement, je transformerais le script en une fonction et j'enverrais le tout à festival avec tee entre les deux (qui envoie le texte à la fois sur l'écran et sur le tuyau).

Il y a cependant trois problèmes de syntaxe à régler :

  • read $input devrait être read input . El $ Le symbole déréférence la variable dans le script Shell (c'est-à-dire qu'il $input sera remplacé par ce que input tient).
  • Vous n'avez pas yes y no les variables déclarées. Ce que vous devriez faire, c'est une comparaison de chaînes de caractères : [ "$input" == "yes" ]
  • Extra ]] en elif

Quant à savoir pourquoi vous avez Hello! tout le temps, c'est exactement à cause des deux premiers points. Avant read $input la variable input n'existe pas, donc vous ne faites qu'exécuter read (c'est-à-dire, variable inexistante $input est déréférencé en chaîne vide, laissant seulement read à cet endroit). Ainsi, tout ce que vous tapez est stocké dans le REPLY qui est ce que read est utilisé lorsqu'aucun nom de variable n'a été donné. Et parce que yes n'existe pas, elle est également remplacée par une chaîne vide. Ainsi, en réalité [ $input == $yes ] est traité comme [ "" == "" ] ce qui est toujours vrai.

$ [ $nonexistent == $anothernonexistent  ] && echo "Success"
Success

Le script fixe devrait être ainsi :

#!/bin/bash
main(){
    read -p "Are you there?" input  

    if [ "$input" == "yes" ]; then  
        echo "Hello!"  
    elif [ "$input" == "no" ]; then  
        echo "Are you sure?"  
    else  
        echo "Please answer yes or no."  
    fi 
}
main | tee /dev/tty | festival --tts

N'oubliez pas de citer les variables et lire sur différence entre = y == dans la commande de test .

2voto

Pankaj Parag Points 317

Une troisième approche consisterait à attribuer une variable commune à chaque cas et, en fin de compte, à agir sur cette variable. Je ne suis pas sûr que cette approche soit courante dans bash, mais dans d'autres langages de programmation, elle est assez standard.

Aussi shopt -s nocasematch en collaboration avec [[ pour la comparaison de chaînes de caractères sans tenir compte de la casse.
Avec cela aussi YES y NO sont considérés comme des entrées valides.

boutique en ligne
[[[](https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html)

#!/bin/bash

shopt -s nocasematch

read -p "Are you there?" input  

if [[ "$input" == "yes" ]]; then  
    msg="Hello!"  
elif [[ "$input" == "no" ]]; then  
    msg="Are you sure?"  
else  
    msg="Please answer yes or no."  
fi 

echo $msg
echo $msg | festival --tts

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X