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

hig*_*guy 10 bash 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="$*"
Run Code Online (Sandbox Code Playgroud)

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

myscript -d myscriptparam -- -d internalparam
Run Code Online (Sandbox Code Playgroud)

exeparams 将举行

-- -d internalparam
Run Code Online (Sandbox Code Playgroud)

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

jw0*_*013 14

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

shift "$((OPTIND - 1))"
Run Code Online (Sandbox Code Playgroud)

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

从那里,您必须将非选项参数(如果有)处理到脚本的第一部分(在 之前--)。一旦遇到--,请将其移出,直到只剩下后一部分(在-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
Run Code Online (Sandbox Code Playgroud)

最后,只剩下第二组选项/参数,您可以传递它们。千万不要使用$*到其余的参数传递给另一个命令。使用"$@"替代,它保留了原有的分词。

external_command "$@"
Run Code Online (Sandbox Code Playgroud)


gle*_*man 7

怎么样:

# ... getopts processing ...

[[ $1 = "--" ]] && shift
exeparams=("$@")
Run Code Online (Sandbox Code Playgroud)

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