You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:05:34