EOF inesperado y error de sintaxis

9

Actualmente estoy escribiendo mi tercer script de shell y me he encontrado con un problema. Este es mi guión hasta ahora:

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

cuando trato de ejecutar el script dice esto:

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

¿Qué estoy haciendo mal?

Swifty124
fuente
1
¿Seguramente quieres decir "EOF", no "ECF"?
l0b0

Respuestas:

5

El problema es que a su casedeclaración le falta el tema, la variable que debe evaluar. Por lo tanto, probablemente quieras algo como esto:

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

Aquí caseusa la variable predeterminada $REPLYque se readllena cuando no se le da ningún nombre de variable (ver help readpara más detalles).

También tenga en cuenta los cambios: printfse usa para mostrar el mensaje en cada ronda (y no agrega una nueva línea), catse usa para imprimir instrucciones en varias líneas para que no se envuelvan y sean más fáciles de leer.

Peterph
fuente
6

No olvidemos 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
Glenn Jackman
fuente
1
Esta parece ser la respuesta más limpia hasta ahora. Utiliza select, que fue diseñado para hacer exactamente lo que requiere el OP. Coloca las opciones en una matriz, que es una excelente manera de manejar datos como este y lo pone a disposición para su uso en otras partes del script. Utiliza break en lugar de salir para que el script pueda hacer algo más después de que se complete esta parte.
Joe
2

Probemos por un solo caso inicialmente. Usaré read -ppara leer la entrada del usuario en una variable optseguida de una declaración de caso como se muestra a continuación.

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

El script anterior funciona bien y ahora, creo que necesita tenerlo en un bucle para que pueda leer la entrada del usuario hasta que el usuario presione la opción 4.

Entonces, podríamos hacerlo con un whilebucle como a continuación. Establezco la variable optcon el valor inicial en 0. Ahora, estoy iterando en el whilebucle siempre que la optvariable tenga un valor de 0 (por lo que restablezco la optvariable como 0 al final de la casedeclaración).

#!/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
Ramesh
fuente
0

Yo personalmente pondría el "while" al comienzo del código. Si luego lo sigue con un :, le permitirá recorrer tantas veces como lo desee. Así es como lo escribiría.

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

luego continúe con las preguntas y termine con

esac
done
Joe Dale
fuente