Shell 脚本未读取输入
Shell Script not reading input
我写了一个备份和恢复文件的脚本。我有一个问题,当用户输入“2”进行恢复时,程序说这是一个无效输入,所有其他选项都可以正常工作。我觉得这是我遗漏的小东西,但我无法修复它
更新和恢复脚本
#!/bin/bash
ROOT="/Users/Rory/Documents"
ROOT_EXCLUDE="--exclude=/dev --exclude=/proc --exclude=/sys --exclude=/temp --exclude=/run --exlucde=/mnt --exlcude=/media --exlude=/backup2.tgz"
DESTIN="/Users/Rory/test/"
BACKUP="backup2.tgz"
CREATE="/dev /proc /sys /temp /run /mnt /media "
if [ "$USER" != "root" ]; then
echo "You are not the root user"
echo "To use backup please use: sudo backup"
exit
fi
clear
echo "************************************************"
echo "********* Backup Menu **************************"
echo "************************************************"
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
sleep 3
clear
exit
elif [ "$opt" = "BACKUP" ]; then
echo "BACKING UP FILES..."
sleep 2
tar cvpfz $DESTIN/backup.`date +%d%m%y_%k:%M`.tgz $ROOT $ROOT_EXCLUDE_DIRS
echo "BACKUP COMPLETE"
sleep 2
exit
elif [ "$opt" = "RESTORE" ]; then
echo "RESTOTING FILES..."
sleep 2
tar xvpfz $BACKUP_FILE -C /
sleep2
echo "RESTORE COMPLETE..."
if [[ -e "/proc" ]]; then
echo "$CREATE_DIRS allready exists! "
else
mkdir $CREATE_DIRS
echo "$CREATE_DIRS are created! "
fi
exit
elif [ "$opt" = "DESTINATION" ]; then
echo "CURRENT DESTINATION: $DEST_DIR/backup.`date +%d/%m/%y_%k:%M`.tgz "
echo "TO CHANGE ENTER THE NEW DESTINATION..."
echo "TO LEAVE IT AS IS JUST PRESS ENTER..."
read NEW_DESTIN
#IF GREATER THEN 0 ASSIGN NEW DESTINATION
if [ ${#NEW_DESTIN} -gt 0 ]; then
DESTIN = "$NEW_DESTIN"
fi
clear
echo $BANNER1
echo $BANNER2
echo $BANNER3
echo $LIST
else
clear
echo "BAD INPUT!"
echo "ENTER 1 , 2, 3 or 4.."
echo $LIST
fi
done
除了你错过了你设置 ROOT_EXCLUDE
的结尾引号(第 4 行),我觉得还可以。我认为遗漏的引号是转录错误,或者您的程序根本无法正常工作。
我已经试用了该程序,它似乎有效。
一个调试技巧是 set -xv
在脚本中打开调试,set +xv
关闭它。 -x
表示在执行前打印出该行,-v
表示在shell插入该行后打印出该行。
我相信一旦你的程序中有 set -xv
,你就会立即看到这个问题。
作为其中的一部分,您可以将PS4
设置为在打印调试信息时打印的行提示。我喜欢这样设置 PS4:
export PS4="[$LINENO]> "
这样,行提示打印出它正在执行的行,这很好。
在你的情况下,我会把 set -xv
放在你设置 OPTIONS
之前,然后放在程序的最后。这样,您可以查看 if
比较,并可能发现您的问题。
export PS4="[$LINENO]> "
set -xv
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
set +xv
顺便说一句,测试时最好使用双方括号[[ ... ]]
,而不是单方括号[ ... ]
。这与 shell 在测试中插入值的方式有关。
[ ... ]
是内置 test
命令的别名。 shell 按原样插入行并执行整行。
[[ ... ]]
是一个复合语句,其中 shell 将插入变量,但不是整行。该行保持完整:
foo="one thing"
bar="another thing"
这会起作用:
if [ "$foo" = "$bar" ]
then
echo "Foo and bar are the same"
fi
这不会:
if [ $foo = $bar ]
then
echo "Foo and bar are the same"
fi
shell按原样插入线:
if [ one thing = another thing ]
这与:
if test one thing = another thing
test
命令看第一项看是不是标准测试,或者假设三项,第二项是比较。在这种情况下,两者都不是真的。
但是,这会起作用:
if [[ $foo = $bar ]] # Quotes aren't needed
then
echo "Foo and bar are the same"
fi
由于 [[ ... ]]
是一个复合命令,$foo
和 $bar
被替换为它们的值,但它们的位置保持不变。因此,=
被识别为比较运算符。
使用 [[ ... ]]
而不是 [ ... ]
解决了我遇到的很多难以发现的 shell 脚本错误。
我写了一个备份和恢复文件的脚本。我有一个问题,当用户输入“2”进行恢复时,程序说这是一个无效输入,所有其他选项都可以正常工作。我觉得这是我遗漏的小东西,但我无法修复它
更新和恢复脚本
#!/bin/bash
ROOT="/Users/Rory/Documents"
ROOT_EXCLUDE="--exclude=/dev --exclude=/proc --exclude=/sys --exclude=/temp --exclude=/run --exlucde=/mnt --exlcude=/media --exlude=/backup2.tgz"
DESTIN="/Users/Rory/test/"
BACKUP="backup2.tgz"
CREATE="/dev /proc /sys /temp /run /mnt /media "
if [ "$USER" != "root" ]; then
echo "You are not the root user"
echo "To use backup please use: sudo backup"
exit
fi
clear
echo "************************************************"
echo "********* Backup Menu **************************"
echo "************************************************"
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
sleep 3
clear
exit
elif [ "$opt" = "BACKUP" ]; then
echo "BACKING UP FILES..."
sleep 2
tar cvpfz $DESTIN/backup.`date +%d%m%y_%k:%M`.tgz $ROOT $ROOT_EXCLUDE_DIRS
echo "BACKUP COMPLETE"
sleep 2
exit
elif [ "$opt" = "RESTORE" ]; then
echo "RESTOTING FILES..."
sleep 2
tar xvpfz $BACKUP_FILE -C /
sleep2
echo "RESTORE COMPLETE..."
if [[ -e "/proc" ]]; then
echo "$CREATE_DIRS allready exists! "
else
mkdir $CREATE_DIRS
echo "$CREATE_DIRS are created! "
fi
exit
elif [ "$opt" = "DESTINATION" ]; then
echo "CURRENT DESTINATION: $DEST_DIR/backup.`date +%d/%m/%y_%k:%M`.tgz "
echo "TO CHANGE ENTER THE NEW DESTINATION..."
echo "TO LEAVE IT AS IS JUST PRESS ENTER..."
read NEW_DESTIN
#IF GREATER THEN 0 ASSIGN NEW DESTINATION
if [ ${#NEW_DESTIN} -gt 0 ]; then
DESTIN = "$NEW_DESTIN"
fi
clear
echo $BANNER1
echo $BANNER2
echo $BANNER3
echo $LIST
else
clear
echo "BAD INPUT!"
echo "ENTER 1 , 2, 3 or 4.."
echo $LIST
fi
done
除了你错过了你设置 ROOT_EXCLUDE
的结尾引号(第 4 行),我觉得还可以。我认为遗漏的引号是转录错误,或者您的程序根本无法正常工作。
我已经试用了该程序,它似乎有效。
一个调试技巧是 set -xv
在脚本中打开调试,set +xv
关闭它。 -x
表示在执行前打印出该行,-v
表示在shell插入该行后打印出该行。
我相信一旦你的程序中有 set -xv
,你就会立即看到这个问题。
作为其中的一部分,您可以将PS4
设置为在打印调试信息时打印的行提示。我喜欢这样设置 PS4:
export PS4="[$LINENO]> "
这样,行提示打印出它正在执行的行,这很好。
在你的情况下,我会把 set -xv
放在你设置 OPTIONS
之前,然后放在程序的最后。这样,您可以查看 if
比较,并可能发现您的问题。
export PS4="[$LINENO]> "
set -xv
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
set +xv
顺便说一句,测试时最好使用双方括号[[ ... ]]
,而不是单方括号[ ... ]
。这与 shell 在测试中插入值的方式有关。
[ ... ]
是内置 test
命令的别名。 shell 按原样插入行并执行整行。
[[ ... ]]
是一个复合语句,其中 shell 将插入变量,但不是整行。该行保持完整:
foo="one thing"
bar="another thing"
这会起作用:
if [ "$foo" = "$bar" ]
then
echo "Foo and bar are the same"
fi
这不会:
if [ $foo = $bar ]
then
echo "Foo and bar are the same"
fi
shell按原样插入线:
if [ one thing = another thing ]
这与:
if test one thing = another thing
test
命令看第一项看是不是标准测试,或者假设三项,第二项是比较。在这种情况下,两者都不是真的。
但是,这会起作用:
if [[ $foo = $bar ]] # Quotes aren't needed
then
echo "Foo and bar are the same"
fi
由于 [[ ... ]]
是一个复合命令,$foo
和 $bar
被替换为它们的值,但它们的位置保持不变。因此,=
被识别为比较运算符。
使用 [[ ... ]]
而不是 [ ... ]
解决了我遇到的很多难以发现的 shell 脚本错误。