我是shell脚本的新手,我的脚本似乎没问题,但是我正在控制问题。有人能指出我做出的愚蠢错误。
#! /bin/sh
echo "Are you sure youx want to delete $1? Answer y or n"
read ans
echo $ans
if $ans = "y"|"Y"
then
mv $1 /home/parallels/dustbin
echo "File $1 has been deleted"
else echo "File $1 has not been deleted"
fi
答案 0 :(得分:1)
制作你喜欢的if条件:
if [ "$ans" = "y" -o "$ans" = "Y" ]
答案 1 :(得分:1)
您的脚本有一些问题。有些是严肃的,有些则不那么严重。
首先是严重的问题。
正如大师建议的那样,您需要使用方括号来包围if
条件。这是因为if
仅测试条件的输出,它不执行实际的字符串比较。传统上,名为/bin/test
的程序(也称为/bin/[
)负责处理此问题。目前,该功能内置于shell中,但/bin/sh
仍然表现得像是一个单独的程序。
事实上,当您不使用方括号表示条件时,您可以使用if
执行有趣的操作。例如,if grep -q 'RE' /path/to/file; then
很常见。 grep -q
命令不发出输出,只返回if
检测到的“成功”或“失败”。
第二个严重问题是你回应的状态可能是也可能不是。我称这是一个严重的问题,因为......好吧,日志消息根本不应该做出错误的声明。如果$1
中的文件的权限错误,或者文件名包含空格,则您的mv
命令将失败,但该消息将声明它没有。稍后会详细介绍。
接下来,问题不那么严重了。
这些主要是风格和优化的东西。
首先,大多数平台上的read
都包含-p
选项,可让您指定提示。使用此选项,您不需要包含echo
命令。
其次,你的缩进使得很难看到if
构造包装的内容。这对于这么小的程序来说不是一个大问题,但随着你的成长,你真的想要遵循一致的标准。
第三,如果您使用case
语句而不是if
,则可以在选择性问题中获得更大的灵活性。
毕竟,这就是我写这个脚本的方式:
#!/bin/sh
if [ "$1" = "-y" ]; then
ans=y
shift
elif [ -t 0 ]; then
read -p "Are you sure you want to delete '$1' (y/N) ? " ans
fi
case "$ans" in
Y*|y*)
retval=0
if [ -z "$1" ]; then
retval=64
echo "ERROR: you didn't specify a filename." >&2
if [ ! -f "$1" ]; then
retval=66
echo "ERROR: file '$1' not found!" >&2
elif mv "$1" /home/parallels/dustbin/; then
echo "File '$1' has been deleted" >&2
else
retval=$?
echo "ERROR: file '$1' could not be deleted!" >&2
fi
;;
*)
echo "ABORT: file '$1' has not been deleted" >&2
retval=4
;;
esac
exit $retval
除了上面提到的内容之外,以下是此代码段中的一些内容:
[ "$1" = "-y" ]
- 如果用户指定-y
选项,那么我们的行为就好像问题的回答是“是”。[ -t 0 ]
- 这会测试我们是否在互动终端上。如果我们是,那么用read
提问是有意义的。Y*|y*)
- 在case语句中,匹配任何以大写或小写“y”开头的字符串。因此,有效的肯定回答将是“Y”,“是”,“黄色”等。[ ! -f "$1" ]
- 测试文件是否存在。您可以man test
或man sh
查看shell中可用的各种测试。 (-f
可能不适合您。)>&2
- 在一行的末尾,将其输出发送到“标准错误”而不是“标准输出”。这会改变管道,cron等处理输出的方式。错误和日志数据通常会发送到stderr,因此stdout可以专用于程序的实际输出。mv "$1" ...
- 文件名用引号括起来。如果文件名中包含空格等特殊字符,这可以保护您。$retval
- 此值来自对man sysexits
中最近项的最佳猜测。retval=$?
- 这是最近执行的命令的退出状态。在这种情况下,这意味着我们将mv
的退出状态分配给变量$retval
,这样如果mv
失败,整个脚本会报告失败的原因,目前为止与mv
有关。答案 2 :(得分:0)
您还可以将用户响应转换为任何一种情况,只需检查相应的情况,如
read ans
ans=${ans,,} # make 'ans' lowercase, or use ${ans^^} for making it uppercase
if [ "$ans" = "y" ]
then
....
fi
答案 3 :(得分:0)
以下是包含错误处理的完美代码
#!/bin/sh
echo "Are you sure you want to delete $1? Answer y or n"
read ans
echo $ans
if [ $ans == "y" ] || [ $ans == "Y" ]
then
if [ -f $1 ]
then
mv $1 /home/parallels/dustbin
echo "File $1 has been deleted"
else
echo " File $1 is not found"
fi
else
echo "File $1 has not been deleted"
fi