如何定义一个带参数或不带参数的函数?

How to define a function that either takes arguments or doesnt?

我正在使用 Fish shell... 基本上,做这样的事情:

if (first argument == --r) {
  do something
} else {
  Do something
  if (first argument == --n) {
    do more 
  }
}

为了实现我尝试的第一个 if 语句:

 if test (count $argv) -eq 1 -a $argv[1] = '--r'

但这给出了一个信息: 测试:索引 6

处缺少参数

好吧,如果参数是可选的,那么您可以通过以下方式做到这一点:

//check if variable exists
if (typeof variable === 'undefined'){
}
else{
if(typeof variable){}
}

这对我有用:

if set -q argv[1] ;and test $argv[1] = "--r"

Fish 中的函数不需要在定义函数时指定其参数。用户发送给函数的任何参数都会自动存储在名为 argv 的数组中。为了确定是否发送了参数,您可以计算数组中元素的数量,或者确定数组作为字符串的长度。我做后者:

    function my_func
        if [ -z "$argv" ]; # No arguments
            echo "No arguments supplied"
            return
        else # At least one argument
            if [ "$argv[1]" = "--r" ];
                echo "Excellent!"
                return
            end
        end
    end

如果您更喜欢使用 count,那么它将看起来更像这样:

    function my_func
        if [ (count $argv) -eq 1 -a "$argv[1]" = "--r" ];
            # Exactly one argument with specified value "--r"
            echo "Excellent!"
            return
        else # May have arguments, but none equal to "--r"
            echo "Give me the right arguments"
            return
        end
    end

您使用 set -q argv[1] 也是一个不错的选择。但是当你检查字符串是否相等时,不要忘记用引号将你的变量括起来,像这样:test "$argv[1]" = "--r".

这是另一种方法,使用 switch...case 条件测试:

    function my_func
        # No arguments
        if [ -z "$argv" ]; and return

        # At least one argument
        switch $argv[1];
            case --r;
                # do some stuff
                return
            case "*";
                # Any other arguments passed
                return
            end
        end
    end

让我们从执行此操作时遇到的错误开始:

if test (count $argv) -eq 1 -a $argv[1] = '--r'

发生这种情况是因为 fish 首先扩展 $argv[1] 然后执行 test。如果 argv 没有值,那么该语句变成

if test 0 -eq 1 -a  = '--r'

test 命令的语法无效。第一个 sub-expression 的计算结果为 false 无关紧要,因为 test 在计算之前解析了整个表达式。

而不是 test (count $argv) -eq 1 只是 set -q argv[1] 来测试 argv 是否至少有一个参数。注意缺少 dollar-sign.

如果您使用的是 fish 2.7.0 或更新版本,我推荐使用新的 argparse 内置函数来处理参数。 fish 附带的几个标准函数使用它,因此您可以查看它们,以及 man argparse,以获取如何使用它的示例。使用 argparse 几乎总是更安全,不太可能由于使用手写的 fish 脚本进行草率的参数解析而导致错误,并且将提供与大多数命令(包括所有 fish 内置命令)相同的参数解析语义。包括正确处理短标志和长标志。