EOF imprevisto ed errore di sintassi


9

Attualmente sto scrivendo il mio terzo script di shell in assoluto e ho riscontrato un problema. Questa è la mia sceneggiatura finora:

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

quando provo a eseguire lo script dice questo:

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

Che cosa sto facendo di sbagliato?


1
Sicuramente intendi "EOF", non "ECF"?
l0b0

Risposte:


5

Il problema è che alla tua casedichiarazione manca l'oggetto - la variabile che dovrebbe valutare. Quindi probabilmente vuoi qualcosa del genere:

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

Qui caseutilizza la variabile predefinita $REPLYche si readriempie quando non viene assegnato alcun nome di variabile (vedere help readper i dettagli).

Nota anche le modifiche: printfviene utilizzato per visualizzare il prompt in ogni round (e non aggiunge una nuova riga), catviene utilizzato per stampare le istruzioni su più righe in modo che non si avvolgano e siano più facili da leggere.


6

Non dimentichiamo 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
Questa sembra la risposta più pulita finora. Usa select che è stato progettato per fare esattamente ciò che richiede l'OP. Mette le scelte in un array che è un ottimo modo per gestire dati come questo e li rende disponibili per l'uso altrove nello script. Usa break piuttosto che exit in modo che lo script possa fare qualcos'altro dopo aver terminato questa parte.
Joe,

2

Proviamo inizialmente per un singolo caso. Userò read -pper leggere l'input dell'utente in una variabile optseguita dall'istruzione case come di seguito.

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

Lo script sopra funziona bene e ora, credo che tu debba averlo in un ciclo in modo da poter leggere l'input dell'utente fino a quando l'utente preme l'opzione 4.

Quindi, potremmo farlo con un whileciclo come di seguito. Ho impostato la variabile optcon il valore iniziale su 0. Ora sto ripetendo il whileciclo finché la optvariabile ha un valore pari a 0 (motivo per cui ho reimpostato la optvariabile come 0 alla fine casedell'istruzione).

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

Personalmente metterei il "while" all'inizio del codice. Se poi lo segui con un :, gli permetterà di girare in loop tutte le volte che vuoi. È così che lo scriverei.

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
            ;;

quindi continua con le domande e finisci con

esac
done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.