我正在尝试用脚本 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
我正在尝试用脚本 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
你为什么使用${@:$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
如果可能的话,干脆忽略那些额外的参数。
为了将命令选项与常规参数分开,您需要知道哪些选项带有参数,哪些是独立的。
在示例命令中:
./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,作为单独的单词传递”。