有没有办法避免 bash 中的位置参数? [英] Is there a way to avoid positional arguments in bash?

查看:29
本文介绍了有没有办法避免 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:

调用带参数的函数:

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 风格的选项解析.

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

另见:在 bash shell 脚本中使用 getopts 获取长短命令行选项

你也可以偷懒,只将变量"作为参数传递给函数,即:

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(我认为),你也可以尝试使用关联数组.它将允许您传递命名参数,但它难看.类似的东西:

args=( [from]=/tmp/a [to]=/tmp/b )
copy args

然后在 copy() 中,您需要 获取数组.

And then in copy(), you'd need to grab the array.

这篇关于有没有办法避免 bash 中的位置参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆