前几天发现小伙伴写的 shell 脚本在参数正常时执行正常,在参数异常时执行出现死循环了。
参考前文 在Bash中解析命令行参数的两种样例脚本 代码,将相关代码改为如下 demo 程序:
#!/bin/bash
POSITIONAL_ARGS=() #初始化一个空数组,用来存储位置参数
while [[ $# -gt 0 ]]; do #当命令行参数的数量大于0时,进入循环
case $1 in
-e|--extension) #如果参数是这个,脚本会将紧随其后的参数(文件扩展名)保存在变量 EXTENSION 中
EXTENSION="$2"
shift 2 # 跳过参数 和 后面的值
;;
-s|--searchpath) #如果参数是这个,脚本会将紧随其后的参数(搜索路径)保存在变量 SEARCHPATH 中
SEARCHPATH="$2"
shift 2 # 跳过参数 和 后面的值
;;
--default) #如果参数是这个,脚本会将变量 DEFAULT 设置为 YES
DEFAULT=YES
shift # 跳过参数
;;
-*|--*) #如果参数是以 - 或 -- 开头且未知的选项,打印错误信息并退出
echo "Unknown option $1"
exit 1
;;
*) #对于所有其他非选项参数(即位置参数),将它们逐一添加到 POSITIONAL_ARGS 数组中,
POSITIONAL_ARGS+=("$1") # 保存位置参数
shift
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # 将数组里的参数设置为当前 shell 的位置参数
echo "FILE EXTENSION = ${EXTENSION}"
echo "SEARCH PATH = ${SEARCHPATH}"
echo "DEFAULT = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "The non option arguments are:" $@
fi
不同的点在于将样例代码中连续的两行 shift
合为一行 shift 2
。
测试效果如下:
于是使用命令 bash -x demo-space-separated.sh -e
调试一下,输出信息如下:
根据打印输出并结合脚本代码可知,程序出现了死循环,参数个数 $# 没能减为0,一直在 while 循环里面跳转。
修改回两行 shift 的代码,再测试效果如下:
没有死循环了,会有相应的提示信息。