简体   繁体   English

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

[英]Fish shell: Check if argument is provided for function

I am creating a function (below) with which you can provide an argument, a directory. 我正在创建一个函数(下面),您可以使用该函数提供参数,目录。 I test if the $argv is a directory with -d option, but that doesn't seem to work, it always return true even if no arguments are supplied. 我测试$argv是否是带-d选项的目录,但这似乎不起作用,即使没有提供参数,它也总是返回true。 I also tried test -n $argv -a -d $argv to test is $argv is empty sting, but that returns test: Missing argument at index 1 error. 我也试过test -n $argv -a -d $argv来测试$argv是空的sting,但是返回test: Missing argument at index 1错误。 How should I test if any argument is provided with the function or not? 我该如何测试函数是否提供了任何参数? Why is test -d $argv not working, from my understanding it should be false when no argument is provided, because empty string is not a directory. 为什么test -d $argv不起作用,根据我的理解,当没有提供参数时它应该是假的,因为空字符串不是目录。

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

Thanks for the help. 谢谢您的帮助。

count is the right way to do this. count是执行此操作的正确方法。 For the common case of checking whether there are any arguments, you can use its exit status: 对于检查是否存在任何参数的常见情况,您可以使用其退出状态:

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

To answer your second question, test -d $argv returns true if $argv is empty, because POSIX requires that when test is passed one argument, it must "Exit true (0) if $1 is not null; otherwise, exit false". 要回答你的第二个问题,如果$argv为空, test -d $argv返回true,因为POSIX要求当test传递一个参数时,它必须“如果$ 1不为null则退出true(0);否则,退出false”。 So when $argv is empty, test -d $argv means test -d which must exit true because -d is not empty! 所以当$ argv为空时, test -d $argv意味着test -d必须退出true,因为-d不为空! Argh! 哎呀!

edit Added a missing end , thanks to Ismail for noticing 编辑添加了一个缺失的end ,感谢Ismail注意到

In fish 2.1+ at least, you can name your arguments, which then allows for arguably more semantic code: 至少在鱼2.1+中,您可以命名您的参数,然后允许更多的语义代码:

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

$argv is a list , so you want to look at the first element, if there are elements in that list: $argv是一个列表 ,因此如果该列表中有元素,您需要查看第一个元素:

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

Maybe is non related, but i would like to add another perspective for the question. 也许是无关的,但我想为这个问题添加另一个视角。

I want to broaden the insight to a wider scope the scope of testing the shell code with the libraries developed in the fisherman group. 我希望通过渔民小组开发的库,将更深入的范围扩展到测试shell代码的范围。

With mock you can check if the open command is called safely without side effects. 使用mock,您可以检查是否安全地调用open命令而没有副作用。

Example.: 例。:

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

Is a recent library, but it could help to test things that might be dangerous, like for example rm 是一个最近的库,但它可以帮助测试可能有危险的事情,例如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

I hope that it gives a more out of the box point of view 我希望它能提供更多开箱即用的观点

PS: Sorry for the blatant publicity, but i think that is a cool idea that would be nice to be adopted by shell scripters, to test and add sustainability to shell scripts is nuts. PS:对于公然的宣传感到抱歉,但我认为这是一个很酷的想法,很好被shell脚本编写者采用,测试和增加shell脚本的可持续性是疯了。 :P :P

EDIT: i recently noticed a bug about the sample i posted. 编辑:我最近发现了一个关于我发布的样本的错误。 Please do not use rm *, because the asterisk is not treated as a param, instead fish shell expands asterisk to the list of files found and the command only mocks the first call, this means that the first file would be ignored by the mock, but all the subsequent files will get erased so please be careful if trying the sample and use a single file for the example not the wildcard. 请不要使用rm *,因为星号不被视为参数,而是fish shell将星号扩展为找到的文件列表,命令只会模拟第一次调用,这意味着模拟会忽略第一个文件,但是所有后续文件都将被删除,因此如果尝试使用示例并使用单个文件作为示例而不是通配符,请小心。

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

From the man set page: man set页面:

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

o -q or --query test if the specified variable names are defined. o -q或--query测试是否定义了指定的变量名称。 Does not output anything, but the builtins exit status is the number of variables specified that were not defined. 不输出任何内容,但内置退出状态是指定的未定义的变量数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM