Ошибки сценариев оболочки Bash: ./myDemo: 56: синтаксическая ошибка: строка без кавычек

Может ли кто-нибудь взглянуть на этот код и выяснить, что с ним не так?

#!/bin/sh
while :
do
    echo " Select one of the following options:"
    echo " d or D) Display today's date and time"
    echo " l or L) List the contents of the present working directory"
    echo " w or W) See who is logged in"
    echo " p or P) Print the present working directory"
    echo " a or A) List the contents of a specified directory"
    echo " b or B) Create a backup copy of an ordinary file"
    echo " q or Q) Quit this program"
    echo " Enter your option and hit <Enter>: \c"
    read option 
    case "$option" in
        d|D) date
             ;;
        l|L) ls $PWD
             ;;
        w|w) who
                 ;;
        p|P) pwd
             ;;
        a|A) echo "Please specify the directory and hit <Enter>: \c"
             read directory
                    if [ "$directory = "q" -o "Q" ]
                then
                    exit 0
                fi

                while [ ! -d "$directory" ]
                do
                        echo "Usage: "$directory" must be a directory."
                    echo "Re-enter the directory and hit <Enter>: \c"
                    read directory

                        if [ "$directory" = "q" -o "Q" ]
                        then    
                            exit 0

                        fi

                done
                    printf ls "$directory"

            ;;  
            b|B) echo "Please specify the ordinary file for backup and hit <Enter>: \c"
             read file
                if [ "$file" = "q" -o "Q" ]
                then
                    exit 0
                fi     

                while [ ! -f "$file" ]
                do
                    echo "Usage: \"$file\" must be an ordinary file."
                    echo "Re-enter the ordinary file for backup and hit <Enter>: \c"
                    read file
                        if [ "$file" = "q" -o "Q" ]
                        then
                            exit 0
                        fi              
                done
                    cp "$file" "$file.bkup"
                 ;;

        q|Q) exit 0
             ;;

    esac
    echo
done
exit 0

Есть некоторые синтаксические ошибки, которые я не могу понять. Однако я должен отметить, что в этой системе unix echo -e не работает (не спрашивайте меня, почему я не знаю, и у меня нет никаких разрешений на его изменение, и даже если бы мне не разрешили к)

Ошибка сценария оболочки Bash: «./myDemo ./myDemo: строка 62: синтаксическая ошибка рядом с неожиданным токеном done' ./myDemo: line 62:» [отредактировано]

EDIT: я исправил ошибку оператора while, однако теперь, когда я запускаю скрипт, некоторые вещи по-прежнему работают неправильно.

  1. Похоже, что в операторе b|B) switch

    cp $file $file.bkup фактически не копирует файл в file.bkup ?

  2. В операторе a|A) switch

ls "$directory" не выводит список каталогов для просмотра пользователем ?

#!/bin/bash
while $TRUE
do
        echo " Select one of the following options:"
        echo " d or D) Display today's date and time"
        echo " l or L) List the contents of the present working directory"
        echo " w or W) See who is logged in"
        echo " p or P) Print the present working directory"
        echo " a or A) List the contents of a specified directory"
        echo " b or B) Create a backup copy of an ordinary file"
        echo " q or Q) Quit this program"
        echo " Enter your option and hit <Enter>: \c"
        read option
        case "$option" in
                d|D) date
                     ;;
                l|L) ls pwd
                     ;;
                w|w) who
                     ;;
                p|P) pwd
                     ;;
                a|A) echo "Please specify the directory and hit <Enter>: \c"
                     read directory
                        if [ ! -d "$directory"  ]
                        then
                                while [ ! -d "$directory" ]
                                do
                                        echo "Usage: "$directory" must be a directory."
                                        echo "Specify the directory and hit <Enter>: \c"
                                        read directory

                                        if [ "$directory" = "q" -o "Q" ]
                                        then
                                        exit 0

                                        elif [ -d "$directory" ]
                                        then
                                                ls "$directory"

                                        else
                                        continue
                                        fi
                                done
                        fi
                        ;;
                b|B) echo "Specify the ordinary file for backup and hit <Enter>: \c"
                     read file
                        if [ ! -f "$file" ]
                         then
                                while [ ! -f "$file" ]
                                do 
                                        echo "Usage: "$file" must be an ordinary file."
                                        echo "Specify the ordinary file for backup and hit <Enter>: \c"
                                        read file
                                        if [ "$file" = "q" -o "Q" ]
then
                                        exit 0
                                        elif [ -f "$file" ]
                                        then
                                        cp $file $file.bkup
                                        fi
                                done
                        fi
                        ;;

                q|Q) exit 0
                     ;;

        esac
        echo
done
exit 0

Другое дело... есть ли редактор, который я могу использовать для автоматического анализа кода? То есть что-то похожее на NetBeans?


person 에이바    schedule 07.12.2009    source источник
comment
./myDemo: 6: Синтаксическая ошибка: ) неожиданно (ожидается выполнение)   -  person 에이바    schedule 11.12.2009


Ответы (4)


Вам не хватает do после второго while. (Случай «В»; сравните его со случаем «А» над ним.)

Я использую gvim, который выделяет синтаксис сценариев оболочки, но я думаю, что вам нужно задать вопрос о редакторах как отдельный вопрос.


Что касается вашего модифицированного вопроса: ваша логика нарушена как в случаях A, так и в случаях B: вам нужно вытащить логику резервного копирования из вашего if/while вложенности... if на самом деле ничего для вас не делает. Кроме того, обязательно заключайте в кавычки все имена файлов, чтобы пробелы не нарушали сценарий. Избегайте вложенных кавычек. Я считаю, что вам нужно -e в операторах эха, которые используют \c.

Так что сделайте что-нибудь вроде:

b|B) echo -e "Specify the ordinary file for backup and hit <Enter>: \c"
    read file
    while [ ! -f "$file" ]
    do 
        echo "Usage: \"$file\" must be an ordinary file."
        echo -e "Specify the ordinary file for backup and hit <Enter>: \c"
        read file
        if [ "$file" = "q" -o "$file" = "Q" ]
        then
            exit 0
        fi
    done
    cp "$file" "$file.bkup"
    ;;

Вам нужно будет сделать такие же изменения для случая A.

person retracile    schedule 07.12.2009
comment
Спасибо за помощь в откате. И мне придется попробовать gvim. - person 에이바; 07.12.2009
comment
Я не знал, что \c работает с echo -e в Bash. Я всегда делаю echo -n. - person Dennis Williamson; 07.12.2009
comment
Да, я обычно тоже использую -n. Однако -e позволяет различным \something работать как положено. - person retracile; 07.12.2009
comment
Да, я знаком с -e иначе. - person Dennis Williamson; 08.12.2009

Две проблемы в разделе A) со списком каталогов.

  1. Союз -o работает не так, как вы думаете. Должно быть:

                if [ "$directory" = "q" -o "$directory" = "Q" ]
    
  2. Вашему внешнему «if» требуется «else» для обработки случая, когда указанный каталог действительно является каталогом сразу.

Раздел резервного копирования B) имеет те же две проблемы. Исправьте их, и оба варианта команды будут работать.

person shoover    schedule 07.12.2009

Вы цитировали переменную $file в большинстве мест, но в команде cp этого нет. Так должно быть:

cp "$file" "$file.bkup"

Некоторые из ваших echo команд имеют в конце "\c". Я думаю, что это специфично для csh. Bash будет просто повторять символы «\» и «c» буквально.

Ваш оператор while $TRUE работает благодаря тому, что переменная имеет значение null или не установлена. Если для него установлено какое-то значение, он попытается выполнить содержимое как команду. Если вы хотите сделать такой бесконечный цикл, это обычно делается в Bash следующим образом:

while true

где true встроенная оболочка. Или:

while :

где двоеточие означает отсутствие операции, которое возвращает true. Конечно, есть и другие способы сделать то же самое.

В случае l|L) вы, вероятно, захотите сделать либо:

ls

or

ls $PWD

как у вас сейчас, он попытается перечислить запись для файла с именем «pwd».

И vim, и nano могут подсвечивать синтаксис для Bash. Если они еще не настроены в ~/.nanorc и ~/.vimrc, вы можете сделать это:

для нано:

nano -Y sh scriptname

Для вим:

:syntax on
:set filetype=sh
person Dennis Williamson    schedule 07.12.2009
comment
Хороший улов на while $TRUE и ls pwd; Я пропустил их в своем ответе. - person retracile; 07.12.2009
comment
\c не является csh. Некоторые из старых (до POSIX) оболочек использовали завершающий \c для подавления новой строки, и устаревший стандарт X/Open включает его. Попробуйте это на машине Solaris, используя /usr/xpg4/bin/sh: echo hello\c. - person Idelic; 08.12.2009

1) вы не должны использовать так много эхо.. для создания системы меню вы можете использовать cat here-document, например

cat <<EOF
-------------------------------------------------------
Select one of the following options:
d or D) Display today's date and time
l or L) List the contents of the present working directory
w or W) See who is logged in
p or P) Print the present working directory
a or A) List the contents of a specified directory
b or B) Create a backup copy of an ordinary file
q or Q) Quit this program
--------------------------------------------------------
EOF

или даже это будет делать

echo "-------------------------------------------------------
Select one of the following options:
d or D) Display today's date and time
l or L) List the contents of the present working directory
w or W) See who is logged in
p or P) Print the present working directory
a or A) List the contents of a specified directory
b or B) Create a backup copy of an ordinary file
q or Q) Quit this program
--------------------------------------------------------"

2) при запросе использования для выбора опции вы можете использовать read с -p, например

read -p "Enter your option and hit <Enter>: " choice

3) printf более переносим, ​​чем echo, поэтому вы должны использовать его, когда это возможно.

person ghostdog74    schedule 10.12.2009
comment
Я исправил все операторы эха в соответствии с вашими указаниями. Теперь это моя ошибка: ./myDemo ./myDemo: 6: Синтаксическая ошибка:) неожиданно (ожидание выполнено) - person 에이바; 11.12.2009