fishshell:检查是否为函数提供了参数

cmssoen2  于 2023-04-12  发布在  Shell
关注(0)|答案(5)|浏览(122)

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

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

谢谢你的帮助

wtlkbnrh

wtlkbnrh1#

$argv是一个 list,所以你想看看第一个元素,如果列表中有元素:

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

fwzugrvs2#

也许是不相关的,但我想为这个问题添加另一个Angular 。
我想把视野扩大到更大的范围,即用fisherman组开发的库测试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脚本添加可持续性是疯狂的。
编辑:我最近注意到一个关于我发布的示例的bug。请不要使用rm *,因为星号不被视为参数,而是fish shell将星号扩展到找到的文件列表,并且命令只模拟第一个调用,这意味着第一个文件将被mock忽略,但所有后续文件将得到 * 擦除 *,所以请小心,如果尝试的例子,并使用一个单一的文件的例子,而不是通配符.

eivgtgni

eivgtgni3#

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

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

为了回答第二个问题,如果$argv为空,则test -d $argv返回true,因为POSIX要求当向test传递一个参数时,它必须“如果$1不为空,则退出true(0);否则,exit false”.所以当$argv为空时,test -d $argv意味着test -d必须退出true,因为-d不为空!

  • edit* 添加了一个缺失的end,感谢Ismail的注意
6ioyuze2

6ioyuze24#

至少在fish2.1+中,你可以命名你的参数,这样就可以允许更多的语义代码:

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

7nbnzgx95#

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

man set页面:

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

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

相关问题