web-dev-qa-db-ja.com

Fish Shell:関数の引数が指定されているかどうかを確認します

引数、ディレクトリを指定できる関数(以下)を作成しています。 $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

助けてくれてありがとう。

26
user14492

countがこれを行う正しい方法です。引数があるかどうかを確認する一般的なケースでは、その終了ステータスを使用できます。

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

2番目の質問に答えるには、test -d $argvは、$argvは空です。POSIXでは、testに1つの引数が渡されると、「$ 1がnullでない場合はtrue(0)を終了し、それ以外の場合はfalseを終了する」必要があるためです。したがって、$ argvが空の場合、test -d $argv 手段 test -dは、trueで終了する必要があるため、-dは空ではありません!ああ!

編集通知のためのIsmailのおかげで、欠落しているendを追加しました

34
ridiculous_fish

魚2.1以降では、引数に名前を付けることができます。これにより、おそらくよりセマンティックなコードが可能になります。

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

$argvlistなので、リストに要素がある場合、最初の要素を確認します。

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

多分関連がないかもしれませんが、私は質問に別の視点を追加したいと思います。

漁師グループで開発されたライブラリを使用してシェルコードをテストするスコープをより広い範囲に広げたいと思います。

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

私はそれがボックスの観点からもっと多くを与えることを願っています

PS:露骨な宣伝には申し訳ありませんが、シェルスクリプトに持続可能性をテストして追加するためにシェルスクリプトに採用されるのは素晴らしいアイデアだと思います。 :P

編集:私は最近、投稿したサンプルに関するバグに気づきました。 rm *は使用しないでください。アスタリスクはパラメーターとして扱われません。代わりに、fish Shellはアスタリスクを見つかったファイルのリストに展開し、コマンドは最初の呼び出しのみをモックします。つまり、最初のファイルはモックによって無視されます。ただし、後続のすべてのファイルはerasedになるため、サンプルを試し、ワイルドカードではなく例として単一のファイルを使用する場合は注意してください。

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

から man setページ:

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

o -qまたは--query指定された変数名が定義されているかどうかをテストします。何も出力しませんが、組み込みの終了ステータスは、定義されていない指定された変数の数です。

1
Duke