web-dev-qa-db-fra.com

Fish Shell: Vérifiez si l'argument est fourni pour la fonction

Je crée une fonction (ci-dessous) avec laquelle vous pouvez fournir un argument, un répertoire. Je teste si le $argv est un répertoire avec l’option -d, mais cela ne semble pas fonctionner, il renvoie toujours la valeur true, même si aucun argument n’est fourni. J'ai aussi essayé de tester test -n $argv -a -d $argv si $argv est vide, mais cela retourne une erreur test: Missing argument at index 1. Comment tester si un argument est fourni avec la fonction ou non? Pourquoi test -d $argv ne fonctionne-t-il pas? À ma connaissance, il devrait être faux si aucun argument n'est fourni, car la chaîne vide n'est pas un répertoire.

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

Merci pour l'aide.

18
user14492

count est la bonne façon de faire cela. Pour le cas courant de vérification s’il existe des arguments, vous pouvez utiliser son statut de sortie:

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

Pour répondre à votre deuxième question, test -d $argv renvoie true si $argv est vide, car POSIX exige que, lorsque test reçoive un argument, il doit "Quitter true (0) si $ 1 n'est pas null; sinon, quitter false". Donc, lorsque $ argv est vide, test -d $argv signifie test -d qui doit quitter true car -d n'est pas vide! Argh!

edit Ajout d'une end manquante, merci à Ismail d'avoir remarqué

27
ridiculous_fish

Dans fish 2.1+ au moins, vous pouvez nommer vos arguments, ce qui permet alors un code plus sémantique:

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

$argv est un list , vous voulez donc regarder le premier élément, s'il y a des éléments dans cette liste:

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

Peut-être n’est-il pas lié, mais j’aimerais ajouter une autre perspective à la question.

Je souhaite élargir le champ d'application du test du code Shell aux bibliothèques développées par le groupe de pêcheurs.

Avec mock vous pouvez vérifier si la commande open est appelée en toute sécurité sans effets secondaires.

Exemple.: 

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

Est-ce une bibliothèque récente, mais cela pourrait aider à tester des choses qui pourraient être dangereuses, comme par exemple 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

J'espère que ça donne un point de vue plus original

P.S .: Désolé pour la publicité flagrante, mais je pense que c’est une bonne idée qu’il serait agréable d’être adopté par les scripteurs de Shell, tester et ajouter de la durabilité aux scripts de Shell est dingue. : P

EDIT: j'ai récemment remarqué un bug sur l'exemple que j'ai posté. N'utilisez pas rm *, car l'astérisque n'est pas traité comme un paramètre. Fish Shell ajoute l'astérisque à la liste des fichiers trouvés et la commande ne fait que simuler le premier appel. Cela signifie que le premier fichier serait ignoré, mais tous les fichiers suivants obtiendront effacé , soyez donc prudent si vous essayez l'exemple et utilisez un seul fichier pour l'exemple, pas le caractère générique.

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

De la page man set:

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

o -q ou --query test si les noms de variables spécifiés sont définis. N'affiche rien, mais l'état de sortie intégré est le nombre de variables Spécifiées qui n'ont pas été définies.

0
Duke