如何让一个普通的bash函数,可以接受通过定位和命名参数信息 [英] how to make a generic Bash function that can accept information via positional and named arguments

查看:189
本文介绍了如何让一个普通的bash函数,可以接受通过定位和命名参数信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了大量的巴什功能,这些功能是能够在命令行中获取不同的信息传递使用位置参数的的命名参数(由 getopts的)。这个想法是,位置参数是briskness和人类直接控制被主要用于同时命名参数在很大程度上是为了清楚和控制由其它功能使用。为了说明我是多么想这个,认为可以从一件事转换到另一个功能。这个函数可用于,从广义上讲,在快速模式或在高级模式。在快速模式下,一些参数指定,并且通常是位置参数,而在高级模式下,可以指定多个参数,一般来说,被命名参数。有关示例...

I'm writing a large number of Bash functions that are to be capable of acquiring different pieces of information from the command line passed using positional arguments or named arguments (provided by getopts). The idea is that positional arguments are to be used largely for briskness and direct human control while named arguments are to be used largely for clarity and control by other functions. To illustrate how I am thinking about this, consider a function that can convert from one thing to another. This function can be used, broadly speaking, in a quick mode or in an advanced mode. In the quick mode, few arguments are specified and, generally, are positional arguments, while in the advanced mode, many arguments can be specified and, generally, are named arguments. For examples...

此模式可以以一种方式被使用,例如以下:

This mode can be used in a manner such as the following:

function fileName1 fileName2

它使用自动成为内部的假设和测量一个文件转换到另一个。

It converts one file to another using internal assumptions and measurements made autonomously.

此模式可以以一种方式被使用,例如以下:

This mode can be used in a manner such as the following:

function -i fileName1 -o fileName2 -m -r 100 -v

此模式也可使用,其方式如以下

This mode can be used also in a manner such as the following:

function -m -v fileName1 fileName2 -r 100

注意 -v 不接受任何参数。它是唯一的(指定一些诸如冗长)选项。

Note that -v accepts no argument. It is an option only (specifying something such as verbosity).

因此​​,在这种情况下,逻辑将是第一的位置的参数假定为 FILENAME1 第二位置参数假定为为文件名2 除非的这两种文件名使用指定的 -i -o 选项,在这种情况下的 <他们/ em>的使用,因为它们被赋予较高的优先级(与第一和第二的位置参数被忽略)。

So, the logic in this case would be that the first positional argument is assumed to be fileName1 and the second positional argument is assumed to be fileName2 unless either of these file names are specified using the -i or -o options, in which case they are used because they are given higher priority (and the first and second positional arguments are ignored).

我要求的建议和指导中的作为一般的方式可能的,因为这种方法是被应用到超过150的函数库。

I ask for suggestions and guidance in implementing these types of requirements in as general a way as possible because this approach is to be applied to a library of over 150 functions.

推荐答案

请注意,如果您使用 getopts的,<一个href=\"http://stackoverflow.com/questions/11742996/shell-script-is-mixing-getopts-with-positional-parameters-possible\">all定位参数的必须跟从任何选项。第二个需要注意的是,如果你使用 getopts的解析参数的函数,您必须重置全局 OPTIND 解析任何选项后变量设置为1。否则,我认为解决的办法是简单的:

Be aware that if you use getopts, all positional arguments must come after any options. A second caveat is that if you use getopts to parse arguments to a function, you must reset the global OPTIND variable to 1 after parsing any options. Otherwise I think the solution is straightforward:

#!/usr/bin/env bash

func() {
    local args=$*
    local input output verbose
    local r="unset" m=0 verbose=0

    while getopts i:o:mr:v opt; do
        case "$opt" in
            i) input="$OPTARG" ;;
            o) output="$OPTARG" ;;
            r) r="$OPTARG" ;;
            m) m=1 ;;
            v) verbose=1 ;;
        esac
    done
    shift $((OPTIND-1))
    OPTIND=1    # reset global variable

    [[ $input ]]  || input=$1
    [[ $output ]] || output=$2

    echo "=== func $args ==="
    echo "input: $input"
    echo "output: $output"
    echo "verbose: $verbose"
    echo "r: $r"
    echo "m: $m"
    echo
}

func fileName1 fileName2
func -i fileName1 -o fileName2 -m -r 100 -v
func -m -v -r 100 fileName1 fileName2

输出

=== func fileName1 fileName2 ===
input: fileName1
output: fileName2
verbose: 0
r: unset
m: 0

=== func -i fileName1 -o fileName2 -m -r 100 -v ===
input: fileName1
output: fileName2
verbose: 1
r: 100
m: 1

=== func -m -v -r 100 fileName1 fileName2 ===
input: fileName1
output: fileName2
verbose: 1
r: 100
m: 1

这篇关于如何让一个普通的bash函数,可以接受通过定位和命名参数信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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