鱼壳:检查是否为功能提供了参数

时间:2015-04-14 18:44:53

标签: function shell fish

我正在创建一个函数(下面),您可以使用该函数提供参数,目录。我测试$argv是否是具有-d选项的目录,但似乎不起作用,即使没有提供参数,它也总是返回true。我还尝试test -n $argv -a -d $argv来测试$argv是空的,但是会返回test: Missing argument at index 1错误。我该如何测试函数是否提供了任何参数?为什么test -d $argv不起作用,根据我的理解,当没有提供参数时它应该是假的,因为空字符串不是目录。

function fcd
     if test -d $argv
         open $argv
     else
         open $PWD
     end
 end

感谢您的帮助。

5 个答案:

答案 0 :(得分:27)

count是执行此操作的正确方法。对于检查是否存在任何参数的常见情况,您可以使用其退出状态:

function fcd
    if count $argv > /dev/null
        open $argv
    else
        open $PWD
    end
end

要回答第二个问题,test -d $argv如果$argv为空则返回true,因为POSIX要求在test传递一个参数时,它必须“如果$ 1则返回true(0)不为null;否则,退出false“。因此,当$ argv为空时,test -d $argv表示test -d必须退出true,因为-d不为空!哎呀!

编辑添加了缺失的end,感谢Ismail注意到

答案 1 :(得分:19)

至少在鱼2.1+中,您可以命名您的参数,然后允许更多的语义代码:

function fcd --argument-names 'filename'
    if test -n "$filename"
        open $filename
    else
        open $PWD
    end
end

答案 2 :(得分:5)

$argv列表,因此如果该列表中有元素,您需要查看第一个元素:

if begin; test (count $argv) -gt 0; and test -d $argv[1]; end
    open $argv[1] 
else
    open $PWD
end

答案 3 :(得分:4)

可能与此无关,但我想为此问题添加另一个视角。

我希望通过渔民小组开发的库,在更广泛的范围内拓展测试shell代码的范围。

使用mock,您可以检查是否安全地调用open命令而没有副作用。

示例:

function fcd
    if count $argv > /dev/null
        open $argv
    else
        open $PWD
    end
end
mock open 0 "echo \$args"
fcd "cool" # echoes cool
mock open 0 "echo \$args"
fcd # echoes $PWD

是一个最近的库,但它可以帮助测试可能有危险的东西,例如rm

mock rm 0 "echo nothing would happen on \$args"
rm "some file" # simply echoes the message with a list of the files that would been affected

我希望它能提供更多开箱即用的观点

P.S。:对于明目张胆的宣传感到抱歉,但我认为这是一个很酷的想法,很好被shell脚本编写者采用,测试和增加shell脚本的可持续性是疯了。 :P

编辑:我最近发现了一个关于我发布的样本的错误。请不要使用rm *,因为星号不被视为参数,而是fish shell将星号扩展为找到的文件列表,命令只会模拟第一次调用,这意味着模拟会忽略第一个文件,但是所有后续文件都会被删除所以请在尝试使用示例时使用单个文件而不是通配符。

答案 4 :(得分:1)

if not set -q argv[1]
    echo 'none'
else
    echo 'yes'
end

man set页上:

   set ( -q | --query ) [SCOPE_OPTIONS] VARIABLE_NAMES...

o -q或--query测试是否定义了指定的变量名。不输出任何内容,但是内建退出状态是指定的变量数          没有定义。