Несподівана помилка EOF та синтаксису


9

В даний час я пишу свій третій сценарій оболонки, і я зіткнувся з проблемою. Це мій сценарій поки:

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

коли я намагаюся запустити сценарій, він говорить так:

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

Що я роблю неправильно?


1
Невже ви маєте на увазі "EOF", а не "ECF"?
l0b0

Відповіді:


5

Проблема полягає в тому, що у вашому caseзаяві відсутня тема - змінна, яку він повинен оцінювати. Отже, ви, мабуть, хочете щось подібне:

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

Тут caseвикористовується змінна за замовчуванням, $REPLYяка readзаповнюється, коли їй не надано імен змінних (див. help readПодробиці).

Також зверніть увагу на зміни: printfвикористовується для відображення підказки у кожному раунді (і не додає новий рядок), catвикористовується для друку інструкцій у декількох рядках, щоб вони не загорталися та були легшими для читання.


6

Не будемо забувати 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
Це виглядає як найчистіша відповідь поки що. Він використовує вибір, який був розроблений для того, щоб робити саме те, що вимагає ОП. Він розміщує вибір у масиві, який є прекрасним способом обробки таких даних і робить його доступним для використання в іншому місці сценарію. Він використовує перерву, а не вихід, так що після виконання цієї частини сценарій може зробити щось інше.
Джо

2

Спробуємо спочатку окремий випадок. Я буду використовувати read -pдля того, щоб прочитати вхід користувача у змінну, optа потім викладений регістр, як показано нижче.

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

Наведений вище сценарій працює чудово, і тепер, я вважаю, вам потрібно мати його в циклі, щоб ви могли читати введення користувача, поки користувач не натисне варіант 4.

Отже, ми могли б зробити це з whileциклом, як показано нижче. Я встановлюю змінну optз початковим значенням як 0. Тепер я повторюю whileцикл до тих пір, поки optзмінна має значення 0 (саме тому я скидаю optзмінну як 0 в кінці caseзаяви).

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

Я особисто поставив би "while" на початку коду. Якщо ви слідуєте за нею :, це дозволить йому обертатися навколо стільки разів, скільки вам захочеться. Ось як би я це написав.

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

потім продовжуйте запитання і закінчуйте

esac
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.