Erro inesperado de sintaxe e EOF

9

Atualmente, estou escrevendo meu terceiro script de shell e já encontrei um problema. Este é o meu script até agora:

#!/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 tento executar o script, ele diz o seguinte:

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

O que estou fazendo errado?

Swifty124
fonte
1
Certamente você quer dizer "EOF", não "ECF"?
L0b0

Respostas:

5

O problema é que sua casedeclaração está faltando no assunto - a variável que deve ser avaliada. Portanto, você provavelmente quer algo assim:

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

Aqui caseusa a variável padrão $REPLYque readpreenche quando não recebe nomes de variáveis ​​(consulte help readpara detalhes).

Observe também as alterações: printfé usado para exibir o prompt em cada rodada (e não acrescenta uma nova linha), caté usado para imprimir instruções em várias linhas, para que não sejam quebradas e sejam mais fáceis de ler.

peterph
fonte
6

Não vamos esquecer 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
fonte
1
Parece a resposta mais limpa até agora. Ele usa o select que foi projetado para fazer exatamente o que o OP exige. Ele coloca as opções em uma matriz, que é uma ótima maneira de lidar com dados como esse e os disponibiliza para uso em outras partes do script. Ele usa break em vez de exit para que o script possa fazer outra coisa depois que essa parte estiver concluída.
Joe
2

Vamos tentar um único caso inicialmente. Usarei read -ppara ler a entrada do usuário em uma variável optseguida pela instrução case, conforme abaixo.

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

O script acima funciona bem e agora, acredito que você precisa tê-lo em loop para poder ler a entrada do usuário até que o usuário pressione a opção 4.

Então, poderíamos fazê-lo com um whileloop como abaixo. Defino a variável optcom o valor inicial como 0. Agora, eu estou iterando no whileloop, desde que a optvariável tenha um valor como 0 (e é por isso que redefino a optvariável como 0 no final da caseinstrução).

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

Eu pessoalmente colocaria o "while" no início do código. Se você segui-lo com a :, permitirá que ele circule quantas vezes você desejar. É assim que eu escreveria.

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

depois continue as perguntas e termine com

esac
done
Joe Dale
fonte