在Bash函数中使用getopts
我想在我在.bash_配置文件中定义的函数中使用在Bash函数中使用getopts,bash,function,getopts,Bash,Function,Getopts,我想在我在.bash_配置文件中定义的函数中使用getopts。 我想把一些标志传递给这个函数来改变它的行为 代码如下: function t() { echo $* getopts "a:" OPTION echo $OPTION echo $OPTARG } 当我这样调用它时: t -a bc 我得到这个输出: -a bc ? 怎么了?我希望在不手动移位和解析的情况下获取值bc。如何在函数中正确使用getopts 编辑:更正了我的代码片段以尝试$OP
getopts
。
我想把一些标志传递给这个函数来改变它的行为
代码如下:
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
当我这样调用它时:
t -a bc
我得到这个输出:
-a bc
?
怎么了?我希望在不手动移位和解析的情况下获取值bc
。如何在函数中正确使用getopts
编辑:更正了我的代码片段以尝试$OPTARG,但无效
编辑#2:好的,代码很好,我的shell不知怎么搞砸了。打开一个新窗口解决了这个问题。arg值实际上是以$OPTARG为单位的 参数存储在变量
$OPTARG
中
function t() {
echo $*
getopts "a:" OPTION
echo $OPTION
echo $OPTARG
}
输出:
$ t -a bc
-a bc
a
bc
$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo
$t-a bc
-公元前
A.
bc
正如@Ansgar所指出的,选项的参数存储在${OPTARG}
中,但在函数内部使用getopts
时,这并不是唯一需要注意的事情。您还需要通过取消设置函数或将其声明为local
,确保函数的${OPTIND}
是本地的,否则在多次调用函数时会遇到意外行为
t.sh
:
#!/bin/bash
foo()
{
foo_usage() { echo "foo: [-a <arg>]" 1>&2; exit; }
local OPTIND o a
while getopts ":a:" o; do
case "${o}" in
a)
a="${OPTARG}"
;;
*)
foo_usage
;;
esac
done
shift $((OPTIND-1))
echo "a: [${a}], non-option arguments: $*"
}
foo
foo -a bc bar quux
foo -x
除此之外,它的用法与在函数外部使用时相同。以下是在shell函数中使用的简单示例:
#!/usr/bin/env bash
t() {
local OPTIND
getopts "a:" OPTION
echo Input: $*, OPTION: $OPTION, OPTARG: $OPTARG
}
t "$@"
t -a foo
输出:
$ t -a bc
-a bc
a
bc
$ ./test.sh -a bc
Input: -a bc, OPTION: a, OPTARG: bc
Input: -a foo, OPTION: a, OPTARG: foo
正如,localoptind
(或OPTIND=1
)需要设置,因为shell不会在(manbash
)之间自动重置OPTIND
)
getopts
的基本语法是:
getopts OPTSTRING VARNAME [ARGS...]
默认情况下,不指定参数相当于使用“$@”显式调用它,即:getopts“a:“opts”$@
如果出现问题,这些是getopts
用来检查的变量:
-要处理的下一个参数的索引OPTIND
-变量设置为由OPTARG
找到的选项的任何参数getopts
(非POSIX)-设置为0或1以指示Bash是否应显示由OPTERR
生成的错误消息getopts
更多信息,请参阅:在Bash黑客维基抱歉,我错误地粘贴了我的代码片段。。。我还回显$OPTARG,这是第三行,空白。还有其他想法吗?@Magnus可能是因为您多次调用该函数,
$OPTIND
没有在本地定义(请参见Adrian的答案)。虽然我很感激您接受了我的答案,但您可能更愿意接受他的答案。代码仅在粘贴到shell中时有效,而在脚本中无效。@kenorb它在脚本中工作得很好。我不是编造出来的。好吧,我不确定如何调用t
,我必须在脚本中调用t-abc
,或者添加t“$@”
,最初我认为它不需要。1.1>&2
中的1
。2.)您没有将a
、o
和OPTARG
定义为本地。3.exit
将不会退出脚本,而只是一个子shell。要退出脚本,必须在外壳中设置-e,并在子外壳中设置退出1。该示例不会引发问题,但一个MSG=$(foo…
会解决问题。@ceving 1)这是一个编码风格的问题,但根据语言定义,这不是必需的。2) 同意,这些应该是本地的。3) 正如您所说,在我的示例中,退出将退出脚本。当然,exit
不会退出子shell,但这不是此问题的具体问题。您不必使用set-e
,只需确保捕捉到错误,MSG=$(foo…)| die
也能正常工作set-e
是解决此问题的一种方法,我和其他许多人一样,不建议使用它。只需指出,即使您在函数中没有使用OPTIND(例如,使用shift;
),它仍然需要本地化,以便具有可预测的行为。@ceving,您可以查看这里,-我添加了local
,但没有很好地给出答案。我不知道它是否有效,但做得很好。@kenorb,你可以在这里查看->,添加了local
,但没有帮助