【问题标题】:Passing command line options to invoked script in bash将命令行选项传递给bash中调用的脚本
【发布时间】:2013-09-28 16:57:43
【问题描述】:

假设我有一个脚本 a.sh 可以使用选项调用

a.sh -a1 a1option -a2 a2option

假设我还有一个脚本b.sh,它调用a.sh 并使用它自己的选项。所以用户执行脚本如下:

b.sh -b1 b1option -b2 b2option -a1 a1option -a2 a2option

现在我想知道如何解析b.sh 中的命令行选项。

我不需要解析 整个 命令行。我不希望b.sh 知道选项a1a2。我只想获得选项b1b2 并将其余的 传递给a.sh

你会怎么做?

【问题讨论】:

    标签: bash shell command-line-arguments


    【解决方案1】:

    如果 a.sh 可以忽略它不知道的选项,您可以使用 b.sh 被调用的所有选项来调用它:

    a.sh "${@}"
    

    【讨论】:

      【解决方案2】:

      根据要求,此方法避免解析整个命令行。只为b.sh 收集到-- 的参数。然后 b 的参数被剥离,只有剩余的参数被传递给a.sh

      b.sh 使用b.sh -b b1option -B b2option -- -a1 a1option -a2 a2option 调用。在这一行中,双破折号-- 表示b.sh 的选项结束。下面解析-- 之前的选项供b.sh 使用,然后从$@ 中删除b 参数,以便您可以将其传递给a.sh,而不必担心a.sh 可能会给您带来什么错误。

      while getopts ":b:B:" opt; do
          case $opt in
              b) B1=${OPTARG}
              ;;
              B) B2=${OPTARG}
              ;;
          esac 
      done
      ## strips off the b options (which must be placed before the --)
      shift $(({OPTIND}-1))
      a.sh "$@"
      

      注意:此方法使用 bash 内置 getopts。 Getopts(相对于 getopt,没有 s)只接受单字符选项;因此,我使用了bB 而不是b1b2

      我最喜欢的getopts 参考。

      【讨论】:

      • -- 分隔符是绝对必要的吗?我可以从列表中的任何位置删除 bB 选项并将列表的rest 传递给a.sh 吗?
      • @Michael:Getopts 从左到右扫描 $@,所以你需要一些方法来告诉 getopts 停止处理选项。 -- 是内置的,所以我用了它。但是,您可以通过将\?) break ;; 添加到案例列表中来告诉它在看到第一个未知选项标志时停止处理,然后您就不需要--。因此,您希望能够以无特定顺序传递选项列表(带或不带参数)?让我看看我能想出什么。
      • @Michael:对于与位置无关的处理,请使用 konsolebox 的版本,它类似但不使用 getopts。将他的案例*) 修改为ARGS_TO_KEEP+=($1);;。然后你应该在数组 ${ARGS_TO_KEEP[@]} 中获取所有非 b 选项和参数。
      【解决方案3】:

      你可以这样做:

      #!/bin/bash
      
      while [[ $# -gt 0 ]]; do
          case "$1" in
          -b1)
              B1=true
              B1OPT=$2
              shift
              ;;
          -b2)
              B2=true
              B2OPT=$2
              shift
              ;;
          --)
              shift
              break
              ;;
          *)
              echo "Invalid option: $1"
              exit 1  ## Could be optional.
              ;;
          esac
          shift
      done
      
      bash a2.sh "$@"
      

      请注意,您应该将变量 $@ 放在双引号内,以防止展开时分词。

      【讨论】:

        猜你喜欢
        • 2018-03-27
        • 2017-07-22
        • 2015-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多