1

我正在尝试用脚本 a 包装 bash 脚本 b。但是,我想将传递给 a 的选项也传递给 b 。

#!/bin/bash

# script a
./b ${@:$OPTIND}

这也将打印 $1(如果有)。最简单的方法是什么?

所以调用:

./a -c -d 5 first-arg

我希望 b 执行: ./b -c -d 5 # WITHOUT first-arg

4

3 回答 3

1
于 2011-04-29T19:49:52.383 回答
0

你为什么使用${@:$OPTIND}而不只是$@or $*

${parameter:index}语法说用于index解析。$parameter如果您使用$@,它将index用作参数的索引。

$ set one two three four #Sets "$@"
$ echo $@
one two three four
$ echo ${@:0}
one two three four
$ echo ${@:1}
one two three four
$ echo ${@:2}
two three four

$OPTIND仅在您使用getopts. getopts这会计算处理 中的参数的次数$@。根据bash 手册页

每次调用 shell 或 shell 脚本时,都会将 OPTIND 初始化为 1。

这可以解释为什么您不断获得1.


针对已编辑的问题进行了编辑

@David - "./b $@ " 仍然打印传递给 a 的参数(参见 Q 编辑)。我只想传递 a 而不是 args 的选项

所以,如果我执行:

$ a -a foo -b bar -c fubar barfu barbar

你想传递给 b:

$ b -a foo -b bar -c fubar

但不是

$ b -arg1 foo -arg2 bar -arg3 fubar barfu barbar

这将是棘手的...

您是否有理由不能将整条线传递给b而忽略它?

我相信可以使用正则表达式:

$ echo "-a bar -b foo -c barfoo foobar" | sed 's/\(-[a-z] [^- ][^- ]*\)  *\([^-][^-]*\)$/\1/'
-a bar -b foo -c barfoo

我不能保证这个正则表达式在所有情况下都有效(即如果没有参数怎么办?)。基本上,我将它锚定到行尾,然后匹配最后一个参数和参数以及该行的其余部分。我只用最后一个参数和参数进行替换。

我已经在几种情况下对其进行了测试,但是您最好使用getopts捕获参数然后将它们传递给b自己,或者b如果可能的话,干脆忽略那些额外的参数。

于 2011-04-29T16:37:41.730 回答
0

为了将命令选项与常规参数分开,您需要知道哪些选项带有参数,哪些是独立的。
在示例命令中:

./a -c -d 5 first-arg
  • -c并且-d可能是独立选项和5 first-arg常规参数
  • 5可能是-d选项的一个参数(这似乎是你的意思)
  • -d可能是-c选项的参数和(如在第一种情况下)5 first-arg常规参数。

以下是我的处理方式,假设,-a和是唯一的选项,并且和是唯一带有选项参数的选项。请注意,有必要解析所有选项以找出它们的结束位置。-b-c-d-b-d

#!/bin/bash

while getopts ab:cd: OPT; do
    case "$OPT" in
        a|b|c|d) : ;; # Don't do anything, we're just here for the parsing
        ?)  echo "Usage: $0 [-ac] [-b something] [-d something] [args...]" >&2
            exit 1 ;;
    esac
done

./b "${@:1:$((OPTIND-1))}"

整个while循环只是为了计算 OPTIND。ab:cd:命令中的定义getopts了允许哪些选项以及哪些选项带有参数(用冒号表示)。神秘的最终表达式表示“参数数组的元素 1 到 OPTIND-1,作为单独的单词传递”。

于 2011-04-29T21:26:55.670 回答