传递函数参数?

传递函数参数?

您将如何创建一个获取参数的函数?

function arg_example {
    arg "c"  # This is imaginary but it would return 'true' if it found the argument -c.
    did_find_arg=$?  # Get the previous function (arg)'s output.

    if [$did_find_arg == 'true']; then
        echo "Yes!"
    else
        echo "Not found."
    fi
}

# Testing
arg_example  # "Not found."
arg_example -c  # "Yes!"
arg_example -k  # "Not found."

另外,如何找到键值函数的值,例如--name

function hello {
    echo "Hello, $--name!"
}

编辑:我知道如何使用$1and $2,但我想知道如何获得可选的东西,如-vor --version

答案1

处理a的命令行功能getopts可以以与处理命令行完全相同的方式完成脚本。唯一需要注意的是OPTIND必须将其重置为 1 或使其成为函数的本地函数:

#!/bin/bash

myfunc () {
    local OPTIND
    local do_c=0
    local do_k=0
    local opt

    while getopts 'ck' opt; do
        case $opt in
            c) do_c=1 ;;
            k) do_k=1 ;;
            *) echo 'Error in command line parsing' >&2
               return 1
        esac
    done
    shift "$(( OPTIND - 1 ))"

    if [ "$do_c" -eq 1 ]; then
        echo 'Yes!'
    else
        echo 'Not found'
    fi
}

myfunc
myfunc -c
myfunc -k
myfunc -a

上述脚本产生:

Not found
Yes!
Not found
script.sh: illegal option -- a
Error in command line parsing

有关的:

答案2

Bash 的非常简单的命名参数提取器:

#!/bin/bash

getargs()
{
  local out=""
  for argname in "$@"; do
    out="${out}local $argname=\$1; shift;"
  done
  printf "%s" "$out"
}

testfun()
{
  eval $(getargs a b c)
  printf "a = %s, b = %s, c = %s\n" "$a" "$b" "$c"
}

testfun "$@"                                                                                                  

由于我们希望参数是函数动态范围内的局部变量testfun,因此getargs不能是函数调用。而是getargs一个小小的编译器它将参数规范转换a b c为 shell句法,生成我们将手动添加的代码,以便将位置参数放入局部变量中。

例如,输出

getargs a b c

是源代码:

local a=$1; shift;local b=$1; shift;local c=$1; shift

当我们eval这样做时,它就会像看起来那样做。在调用者的上下文中,它将前三个位置参数放入ab和 中c,并将它们移出参数列表。

现在我们可以将其提升到一个新的水平并添加“花哨的东西”。

对于初学者来说,生成的代码可以查看实际上确实存在三个论据和诊断。

我们可以支持可选参数:(getargs a b : c或其他)可能意味着ab是必需的,但是c可选的。我们还可以支持尾随参数:getargs a b : c . d可以生成将前两个参数(必需的)获取到 localsab.然后,如果存在第三个参数,则进入c。之后的任何参数都会进入d,这是一个 Bash 数组。

我将把它作为练习。

可惜 shell 没有宏展开时间。这样做的一大缺点是每次调用函数时都会生成代码,即使它是完全静态的。

您可以编写某种预处理器(例如在 Awk 中)将某种命名函数语法糖转换为常规 shell 代码。

相关内容