如何处理选项结束——在 getopts 中

如何处理选项结束——在 getopts 中

我使用 getopts 将 bash 脚本中的参数解析为

while getopts ":hd:" opt; do
  case $opt in
    d ) echo "directory = $OPTARG"; mydir="$OPTARG"; shift $((OPTIND-1)); OPTIND=1 ;;
    h ) helptext
      graceful_exit ;;
    * ) usage
      clean_up
      exit 1
  esac
done

exeparams="$*"

exeparams将保存任何未解析的选项/参数。由于我想使用 exeparams 保存要在脚本内执行的命令的选项(可以与脚本自己的选项重叠),因此我想使用 -- 来结束传递给脚本的选项。如果我通过例如

myscript -d myscriptparam -- -d internalparam

exeparams将举行

-- -d internalparam

我现在想删除前导--以将这些参数传递给内部命令。有没有一种优雅的方法来做到这一点,或者我可以获得一个仅包含其余部分的字符串,而无需--从 getopts 获取?

答案1

使用内置的shift.首先,getopts对脚本执行正常操作。一旦循环完成,

shift "$((OPTIND - 1))"

将移出所有已处理的选项。

从那里,您必须完成对脚本第一部分(在 之前--)的非选项参数(如果有)的处理。一旦遇到--,将其移出,直到只剩下后一部分(-d internalparam后面的部分--)。一种方法(使用bash语法):

while [[ $# -gt 0 ]]; do
    # process next argument
    case $1 in
    foo) # process foo
    ;;
    --) shift; break;; # found '--', discard it and exit loop
    *) # handle unrecognized argument
    ;;
    esac
    # not '--', so discard the argument and continue
    shift
done

最后,只剩下第二组选项/参数,您可以传递它们。做不是用于$*将剩余参数传递给另一个命令。使用"$@"替代,它保留了原始的单词分割。

external_command "$@"

答案2

怎么样:

# ... getopts processing ...

[[ $1 = "--" ]] && shift
exeparams=("$@")

请注意,您应该使用数组来保存参数。这将正确处理任何包含空格的参数。取消引用数组"${exeparams[@]}"

相关内容