Ошибки скриптинга оболочки Bash:./myDemo:56:Синтаксическая ошибка:Незаконченная строка в кавычках
-
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, однако теперь, когда я запускаю скрипт, некоторые вещи по-прежнему не работают корректно.
Похоже, что в операторе b |B) switch
cp $файл $file.bkup не делает на самом деле скопируйте файл в file.bkup ?
В инструкции 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) список каталогов.
Союз -o работает не так, как вы думаете.Должно быть:
if [ "$directory" = "q" -o "$directory" = "Q" ]
Вашему внешнему "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, поэтому вы должны использовать его всякий раз, когда это возможно.