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

StackOverflow https://stackoverflow.com/questions/1861285

  •  13-09-2019
  •  | 
  •  

Вопрос

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

#!/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:" [Отредактировано]

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

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

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

  2. В инструкции a|A) switch

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

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

Это было полезно?

Решение

Вам не хватает do после второго while.(Случай "В";сравните это со случаем "А" выше.)

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


Что касается вашего измененного вопроса:Ваша логика нарушена как в A и B случаи:вам нужно извлечь логику резервного копирования из вашего вложения if / while...в if на самом деле ничего для тебя не делает.Кроме того, обязательно заключайте в кавычки все ваши имена файлов, чтобы пробелы не нарушали ваш скрипт.Экранируйте вложенные кавычки.Я верю, что тебе нужен -e в операторах echo, которые используют \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 кейс.

Другие советы

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

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

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

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

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

cp "$file" "$file.bkup"

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

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

while true

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

while :

где двоеточие - это значение no-op, которое возвращает true.Конечно, есть и другие способы добиться того же самого.

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

ls

или

ls $PWD

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

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

для нано:

nano -Y sh scriptname

Для vim:

:syntax on
:set filetype=sh

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) когда вы просите use выбрать опцию, вы можете использовать read с -p, например

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top