EOF inattendu et erreur de syntaxe


9

J'écris actuellement mon troisième script shell et j'ai rencontré un problème. Voici mon script jusqu'à présent:

#!/bin/bash
echo "choose one of the following options : \
  1) display all current users \
  2) list all files \
  3) show calendar \
  4) exit script"

while read  
do  
 case in  
        1) who;;  
        2) ls -a;;  
        3) cal;;  
        4) exit;;  
 esac    
done

lorsque j'essaie d'exécuter le script, il dit ceci:

line2 : unexpected EOF while looking for matching '"'  
line14 : syntax error: unexpected end of file.    

Qu'est-ce que je fais mal?


1
Vous voulez sûrement dire "EOF", pas "ECF"?
l0b0

Réponses:


5

Le problème est que votre casesujet manque le sujet - la variable qu'il doit évaluer. Par conséquent, vous voulez probablement quelque chose comme ça:

#!/bin/bash
cat <<EOD
choose one of the following options:
1) display all current users
2) list all files
3) show calendar
4) exit script
EOD

while true; do
    printf "your choice: "
    read
    case $REPLY in
        1) who;;
        2) ls -a;;
        3) cal;;
        4) exit;;
    esac    
done

Ici caseutilise la variable par défaut $REPLYqui se readremplit quand on ne lui donne aucun nom de variable (voir help readpour plus de détails).

Notez également les modifications: printfest utilisé pour afficher l'invite à chaque tour (et n'ajoute pas de nouvelle ligne), catest utilisé pour imprimer les instructions sur plusieurs lignes afin qu'elles ne soient pas enroulées et soient plus faciles à lire.


6

N'oublions pas select:

choices=( 
    "display all current users" 
    "list all files" 
    "show calendar" 
    "exit script"
)
PS3="your choice: "
select choice in "${choices[@]}"; do
    case $choice in
        "${choices[0]}") who;;
        "${choices[1]}") ls -a;;
        "${choices[2]}") cal;;
        "${choices[3]}") break;;
    esac
done

1
Cela ressemble à la réponse la plus claire jusqu'à présent. Il utilise select qui a été conçu pour faire exactement ce que l'OP requiert. Il place les choix dans un tableau qui est un excellent moyen de gérer des données comme celle-ci et les rend disponibles pour une utilisation ailleurs dans le script. Il utilise break plutôt que exit pour que le script puisse faire autre chose une fois cette partie terminée.
Joe

2

Essayons d'abord un seul cas. Je vais utiliser read -ppour lire l'entrée utilisateur dans une variable optsuivie d'une déclaration de cas comme ci-dessous.

#!/bin/bash
read -p "choose one of the following options : \
  1) display all current users \
  2) list all files \
  3) show calendar \
  4) exit script" opt
case $opt in
1) who;;
2) ls -a;;
3) cal;;
4) exit;;
esac

Le script ci-dessus fonctionne bien et maintenant, je pense que vous devez l'avoir en boucle afin que vous puissiez lire les entrées de l'utilisateur jusqu'à ce que l'utilisateur appuie sur l'option 4.

Donc, nous pourrions le faire avec une whileboucle comme ci-dessous. J'ai défini la variable optavec la valeur initiale à 0. Maintenant, j'itère dans la whileboucle tant que la optvariable a une valeur à 0 (c'est pourquoi je réinitialise la optvariable à 0 à la fin de l' caseinstruction).

#!/bin/bash
opt=0;
while [ "$opt" == 0 ]
do
read -p "choose one of the following options : \
  1) display all current users \
  2) list all files \
  3) show calendar \
  4) exit script" opt

case $opt in
1) who;;
2) ls -a;;
3) cal;;
4) exit;;
esac
opt=0
done

0

Je mettrais personnellement le "while" au début du code. Si vous le suivez ensuite avec un :, il lui permettra de boucler autant de fois que vous le souhaitez. C'est ainsi que je l'écrirais.

while :
do
    echo "choose one of the following options : \
      1) display all current users \
      2) list all files \
      3) show calendar \
      4) exit script"
    read string
    case $string in
        1)
            who
            ;;

continuez ensuite les questions et terminez par

esac
done
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.