Nieoczekiwany błąd EOF i błąd składni

9

Obecnie piszę mój trzeci skrypt powłoki i napotkałem problem. Oto mój skrypt do tej pory:

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

kiedy próbuję uruchomić skrypt, mówi to:

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

Co ja robię źle?

Swifty124
źródło
1
Z pewnością masz na myśli „EOF”, a nie „ECF”?
l0b0

Odpowiedzi:

5

Problem polega na tym, że w twoim casestwierdzeniu brakuje tematu - zmiennej, którą powinien ocenić. Dlatego prawdopodobnie chcesz czegoś takiego:

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

Tutaj caseużywana jest zmienna domyślna, $REPLYktóra readwypełnia się, gdy nie ma żadnych nazw zmiennych (zobacz help readszczegóły).

Zwróć także uwagę na zmiany: printfsłuży do wyświetlania monitu w każdej rundzie (i nie dodaje nowej linii), catsłuży do drukowania instrukcji w kilku wierszach, aby się nie zawijały i były łatwiejsze do odczytania.

Peter
źródło
6

Nie zapominajmy 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
źródło
1
To jak dotąd najczystsza odpowiedź. Wykorzystuje funkcję select, która została zaprojektowana tak, aby robić dokładnie to, czego wymaga OP. Umieszcza wybory w tablicy, która jest świetnym sposobem na obsługę takich danych i udostępnia je do użycia w innym miejscu skryptu. Używa przerwania zamiast wyjścia, więc skrypt może zrobić coś innego po zakończeniu tej części.
Joe
2

Na początek spróbujmy jednego przypadku. Użyję read -pdo odczytu danych wejściowych użytkownika do zmiennej, opta następnie instrukcji case jak poniżej.

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

Powyższy skrypt działa dobrze i teraz uważam, że musisz go mieć w pętli, abyś mógł czytać dane wejściowe użytkownika, dopóki użytkownik nie naciśnie opcji 4.

Możemy to zrobić za pomocą whilepętli, jak poniżej. Ustawiam zmienną opto wartości początkowej na 0. Teraz iteruję w whilepętli, dopóki optzmienna ma wartość równą 0 (dlatego zeruję optzmienną jako 0 na końcu caseinstrukcji).

#!/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
źródło
0

Osobiście umieściłem „while” na początku kodu. Jeśli następnie zastosujesz się do :niego, pozwoli ci on zapętlać tyle razy, ile chcesz. Tak bym to napisał.

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

następnie kontynuuj pytania i kończ na

esac
done
Joe Dale
źródło