Renvoyer un booléen à partir d'une fonction Bash

Je veux écrire une fonction bash qui vérifie si un fichier a certaines propriétés et renvoie true ou false. Ensuite, je peux l'utiliser dans mes scripts dans le "si". Mais que dois-je retourner?

function myfun(){ ... return 0; else return 1; fi;}

Ensuite, je l'utilise comme ceci:

if myfun filename.txt; then ...

Bien sûr, cela ne fonctionne pas. Comment cela peut-il être réalisé?

159
demandé sur Vadim Kotov 2011-03-25 14:39:08

5 réponses

Utilisez 0 pour vrai et 1 pour faux.

Échantillon:

#!/bin/bash

isdirectory() {
  if [ -d "$1" ]
  then
    # 0 = true
    return 0 
  else
    # 1 = false
    return 1
  fi
}


if isdirectory $1; then echo "is directory"; else echo "nopes"; fi

Modifier

À partir du commentaire de @amichair, ceux-ci sont également possibles

isdirectory() {
  if [ -d "$1" ]
  then
    true
  else
    false
  fi
}


isdirectory() {
  [ -d "$1" ]
}
252
répondu Erik 2017-07-02 20:01:32

Pourquoi vous devriez vous soucier de ce que je dis en dépit d'une réponse upvote 200-ish

Ce n'est pas ça 0 = true et 1 = false. Il est: zéro signifie pas l'échec (succès) et non-zéro signifie l'échec de la (de type N).

, Tandis que le réponse sélectionnée est techniquement "vrai" , veuillez ne pas mettre return 1** dans votre code false. Il aura plusieurs effets secondaires malheureux.

  1. développeurs expérimentés vous repérer comme un amateur (pour la raison ci-dessous).
  2. les développeurs expérimentés ne le font pas (pour toutes les raisons ci-dessous).
  3. Il est sujet aux erreurs.
    • même les développeurs expérimentés peuvent confondre 0 et 1 comme faux et vrai respectivement (pour la raison ci-dessus).
  4. Il exige (ou encouragera) des commentaires étrangers et ridicules.
  5. C'est en fait moins utile que les Statuts de retour implicites.

Apprendre quelques bash

Le manuel bash dit (emphase mine)

Retour [n]

Provoque l'arrêt de l'exécution d'une fonction shell et renvoie la valeur n à son appelant. Si n n'est pas fourni, la valeur de retour est le statut de sortie de la dernière commande exécutée dans la fonction.

Par conséquent, nous n'avons jamais à utiliser 0 et 1 pour indiquer vrai et faux. Le fait qu'ils le fassent est essentiellement une connaissance triviale utile uniquement pour le débogage du code, interview questions, et souffler l'esprit des débutants.

Bash manuel dit aussi:

Sinon, l'état de retour de la fonction est l'état de sortie de la dernière commande exécutée

Bash manuel dit aussi:

($?) se développe à l'état de sortie du pipeline de premier plan le plus récemment exécuté .

Oh, attendez. Pipeline? Passons au manuel bash un de plus temps.

Un pipeline est une séquence de une ou plusieurs commandes séparées par un des opérateurs de contrôle ‘|’ ou ‘|&’.

Oui. Ils ont dit 1 commande est un pipeline. Par conséquent, tous les 3 de ces citations disent la même chose.

  • $? vous dit ce qui s'est passé en dernier.
  • ça bouillonne.

Ma réponse

Donc, alors que @Kambus a démontré qu'avec une fonction aussi simple, Aucun return n'est nécessaire du tout. Je pense que @ Erik's la démonstration était irréaliste par rapport aux besoins de la plupart des gens qui liront ceci.

Pourquoi return?

Si une fonction retourne le statut de sortie de sa dernière commande, pourquoi utiliser return? Parce que cela provoque l'arrêt de l'exécution d'une fonction.

Arrêter l'exécution dans plusieurs conditions

01  function i_should(){
02      uname="$(uname -a)"
03
04      [[ "$uname" =~ Darwin ]] && return
05
06      if [[ "$uname" =~ Ubuntu ]]; then
07          release="$(lsb_release -a)"
08          [[ "$release" =~ LTS ]]
09          return
10      fi
11
12      false
13  }
14
15  function do_it(){
16      echo "Hello, old friend."
17  }
18
19  if i_should; then
20    do_it
21  fi

Ce que nous avons ici est...

Line {[9] } est un retour explicite[-ish] true car le RHS de && n'est exécuté que si le LHS était vrai

Ligne 09 retourne true ou false correspondant à l'état de la ligne 08

Ligne 13 renvoie faux car de ligne 12

(Oui, cela peut être golfé vers le bas, mais l'exemple entier est artificiel.)

Un autre modèle commun

# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
    echo "some_command failed"
fi

# Do this...
some_command
status=$?
if ! $(exit $status); then
    echo "some_command failed"
fi

Remarquez comment définir une variable status démystifie la signification de $?. Mais le vrai retrait est que" si le statut n'existe pas "ou inversement" si le statut de sortie " peut être lu à haute voix et expliquer leur signification. cependant, ce dernier peut être un peu trop ambitieux car voir le mot exit pourrait vous faire penser qu'il sort du script, alors qu'en réalité il sort du sous-shell $(...).


* * Si vous insistez absolument pour utiliser return 1 pour false, je vous suggère au moins d'utiliser return 255 à la place. Cela entraînera votre futur moi, ou tout autre développeur qui doit maintenir votre code à la question " Pourquoi est-ce 255?"Ensuite, ils seront au moins faire attention et ont une meilleure chance de éviter une erreur.

73
répondu Bruno Bronosky 2018-03-16 20:22:20
myfun(){
    [ -d "$1" ]
}
if myfun "path"; then
    echo yes
fi
# or
myfun "path" && echo yes
28
répondu Kambus 2012-09-11 11:17:11

Soyez prudent lorsque vous vérifiez le répertoire uniquement avec l'option-d !
si la variable $ 1 est vide, la vérification sera toujours réussie. Pour être sûr, vérifiez également que la variable n'est pas vide.

#! /bin/bash

is_directory(){

    if [[ -d $1 ]] && [[ -n $1 ]] ; then
        return 0
    else
        return 1
    fi

}


#Test
if is_directory $1 ; then
    echo "Directory exist"
else
    echo "Directory does not exist!" 
fi
13
répondu RenRen 2013-04-25 19:24:15

Cela pourrait fonctionner si vous réécrivez ceci function myfun(){ ... return 0; else return 1; fi;} comme ceci function myfun(){ ... return; else false; fi;}. C'est-à-dire que si false est la dernière instruction de la fonction, vous obtenez un résultat faux pour la fonction entière mais return interrompt la fonction avec un résultat vrai de toute façon. Je crois que c'est vrai pour mon interprète bash au moins.

1
répondu Nephew 2013-06-11 10:57:27