有没有办法避免bash中的位置参数? [英] Is there a way to avoid positional arguments in bash?
问题描述
我必须用bash编写一个函数.该函数将接受约7个参数.我知道我可以调用这样的函数:
I have to write a function in bash. The function will take about 7 arguments. I know that I can call a function like this:
要调用带有参数的函数:
To call a function with parameters:
function_name $arg1 $arg2
我可以在函数中引用这样的参数:
And I can refer my parameters like this inside the function:
function_name () {
echo "Parameter #1 is $1"
}
我的问题是,是否有更好的方法引用函数内部的参数?我可以避免使用$ 1,$ 2,$ 3等吗,而只需使用$ arg1,$ arg2等吗?
My question is, is there a better way refer to the parameters inside the function? Can I avoid the $1, $2, $3, .... thing and simply use the $arg1, $arg2, ...?
是否有合适的方法来执行此操作,或者我需要将这些参数重新分配给函数中的其他一些变量?例如:
Is there a proper method for this or do I need to re-assign these parameters to some other variables inside the function? E.g.:
function_name () {
$ARG1=$1
echo "Parameter #1 is $ARG1"
}
任何例子都将不胜感激.
Any example would be much appreciated.
推荐答案
通常的做法是将参数分配给函数中的局部变量,即:
The common way of doing that is assigning the arguments to local variables in the function, i.e.:
copy() {
local from=${1}
local to=${2}
# ...
}
另一种解决方案可能是 getopt 样式的选项解析.
Another solution may be getopt-style option parsing.
copy() {
local arg from to
while getopts 'f:t:' arg
do
case ${arg} in
f) from=${OPTARG};;
t) to=${OPTARG};;
*) return 1 # illegal option
esac
done
}
copy -f /tmp/a -t /tmp/b
遗憾的是,bash无法处理会更具可读性的长选项,即:
Sadly, bash can't handle long options which would be more readable, i.e.:
copy --from /tmp/a --to /tmp/b
为此,您需要使用外部getopt
程序(我认为该程序仅在GNU系统上具有长选项支持)或手动实现长选项解析器,即:
For that, you either need to use the external getopt
program (which I think has long option support only on GNU systems) or implement the long option parser by hand, i.e.:
copy() {
local from to
while [[ ${1} ]]; do
case "${1}" in
--from)
from=${2}
shift
;;
--to)
to=${2}
shift
;;
*)
echo "Unknown parameter: ${1}" >&2
return 1
esac
if ! shift; then
echo 'Missing parameter argument.' >&2
return 1
fi
done
}
copy --from /tmp/a --to /tmp/b
另请参阅:您也可以偷懒,只需将变量"作为参数传递给函数,即:
You can also be lazy, and just pass the 'variables' as arguments to the function, i.e.:
copy() {
local "${@}"
# ...
}
copy from=/tmp/a to=/tmp/b
,您将在函数中使用${from}
和${to}
作为局部变量.
and you'll have ${from}
and ${to}
in the function as local variables.
请注意,存在与以下相同的问题-如果未传递特定变量,则它将从父环境继承.您可能要添加安全线",例如:
Just note that the same issue as below applies — if a particular variable is not passed, it will be inherited from parent environment. You may want to add a 'safety line' like:
copy() {
local from to # reset first
local "${@}"
# ...
}
确保未通过时未设置${from}
和${to}
.
to ensure that ${from}
and ${to}
will be unset when not passed.
如果您很感兴趣非常糟糕的,则在调用该函数时也可以将参数分配为全局变量,即:
And if something very bad is of your interest, you could also assign the arguments as global variables when invoking the function, i.e.:
from=/tmp/a to=/tmp/b copy
然后您可以在copy()
函数中使用${from}
和${to}
.请注意,然后您应该始终传递所有参数.否则,随机变量可能会泄漏到函数中.
Then you could just use ${from}
and ${to}
within the copy()
function. Just note that you should then always pass all parameters. Otherwise, a random variable may leak into the function.
from= to=/tmp/b copy # safe
to=/tmp/b copy # unsafe: ${from} may be declared elsewhere
如果您具有bash 4.1(我认为),则还可以尝试使用关联数组.它将允许您传递命名参数,但是 很难看.像这样:
If you have bash 4.1 (I think), you can also try using associative arrays. It will allow you to pass named arguments but it will be ugly. Something like:
args=( [from]=/tmp/a [to]=/tmp/b )
copy args
然后在copy()
中,您需要
查看全文