Bash脚本中如何从-d选项获取多个参数?现有脚本存值异常
问题描述
我写了一段Shell脚本代码,想要把-d选项后的所有参数都存储到$DIRS数组中,但执行echo $DIRS时只能得到第一个参数。
脚本代码如下:
#parse options while getopts ":d:b:n:" opt; do case $opt in d) DIRS+=("$OPTARG") echo $DIRS ;; b) PATHBACKUP=$OPTARG echo $PATHBACKUP ;; n) FNAME=$OPTARG echo $FNAME ;; :) echo "Option -$OPTARG requires an argument." >&2 error exit 1 ;; esac done shift $(( OPTIND - 1 ))
执行示例:
./script -d /dev /home/work -b /backup echo $DIRS echo $PATHBACKUP > /dev > /backup
问题原因与解决方法
getopts的默认逻辑是每个选项仅能接收一个参数,所以当你传入-d /dev /home/work时,它只会把/dev识别为-d的参数,/home/work会被当作普通位置参数,不会被-d捕获。
以下两种方案可以解决这个问题:
方案一:重复使用-d选项
修改脚本调用方式,每个需要添加的目录都单独搭配-d:
./script -d /dev -d /home/work -b /backup
这种情况下你的原有代码无需修改,DIRS数组会自动收集所有-d后的参数,后续用echo "${DIRS[@]}"就能输出完整的数组内容。
方案二:修改脚本逻辑,批量捕获-d后的参数
如果不想重复写-d,可以修改脚本逻辑,当匹配到-d时,循环读取后续参数直到遇到新的选项:
#parse options while getopts ":d:b:n:" opt; do case $opt in d) # 先加入第一个参数 DIRS+=("$OPTARG") # 跳过已处理的参数,开始检查后续内容 shift $((OPTIND - 1)) # 循环读取参数,直到遇到以-开头的新选项或参数耗尽 while [[ $# -gt 0 && ! "$1" =~ ^- ]]; do DIRS+=("$1") shift done # 重置OPTIND,让getopts从下一个选项继续处理 OPTIND=1 ;; b) PATHBACKUP=$OPTARG ;; n) FNAME=$OPTARG ;; :) echo "Option -$OPTARG requires an argument." >&2 exit 1 ;; esac done shift $(( OPTIND - 1 ))
这样调用./script -d /dev /home/work -b /backup时,/dev和/home/work都会被加入DIRS数组。注意输出数组必须用echo "${DIRS[@]}",而非echo $DIRS——后者只会输出数组的第一个元素。
内容的提问来源于stack exchange,提问作者T D
相关产品推荐
相关产品推荐

