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

如何让Bash脚本接收完整短选项而非拆分后续字符为参数

问题根因

你遇到的现象是getopts的默认行为导致的:

  • 你的getopts配置中i:表示-i选项必须接收一个参数,当输入-in hello时,-in是同一个命令行参数(token),getopts会直接把i后面紧跟的n作为-i的参数值,这种情况下n不会被识别为独立的选项,自然不会触发非法选项的\?分支。
  • 另外你当前配置里u:表示-u也需要接收参数,但你代码中处理-u的逻辑没有用到$OPTARG,如果这不是你的预期,需要先把u后面的冒号删掉。

解决方法

如果你要求所有选项必须和参数分开写(也就是-i hello合法,-ihello/-in hello非法),可以在处理-i的分支中增加参数合法性校验,检查-i是不是单独作为一个独立的命令行参数存在,不是的话直接调用help。
修改后的完整代码如下:

#!/bin/bash
# 先实现你的help函数,这里给个示例
help(){
  echo "用法: $0 [-i 输入参数] [-u 输入参数]" >&2
  exit 1
}

run(){
  local OPTIND opt iinput uinput
  while getopts ":i:u:" opt; do
    case $opt in
      i)
        # 校验-i是不是单独的参数,避免选项和参数/其他非法选项连写
        if [[ "${@:$((OPTIND-1)):1}" != "-i" ]]; then
          help
        fi
        echo "Typed -i and $OPTARG"
        iinput="$OPTARG"
        ;;
      u)
        # 如果你不需要-u带参数,把optstring里u后面的冒号去掉,同时删掉这行校验
        if [[ "${@:$((OPTIND-1)):1}" != "-u" ]]; then
          help
        fi
        echo "Typed -u and $OPTARG"
        uinput="$OPTARG"
        ;;
      \? | :)
        # 加:分支处理选项缺参数的场景,统一触发help
        help
        ;;
    esac
  done
  shift $((OPTIND -1))
  echo "$iinput"
}
run "$@"

补充说明

  • 如果你不需要-u带参数,只需要把getopts ":i:u:" opt改成getopts ":iu:" opt即可,同时可以去掉-u分支里的校验逻辑。
  • 所有传递给函数的参数建议用双引号包裹"$@",避免参数带空格时解析异常。

内容的提问来源于stack exchange,提问作者user96931

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:15:04