Script bash pour détecter le système de contrôle de version en testant l'état de retour de la commande

11

Je travaille sur un script bash que je voudrais travailler pour plusieurs types de VCS. Je pense à tester si un répertoire est un dépôt pour un système en exécutant une commande info typique et en vérifiant le code retour, le succès ou l'erreur. En pseudo code:

if a svn command succeded;
    Then run svn commands
elif a darcs command succeded;
    Then run darcs commands
elif a mercurial command succeded;
    then run hg commands
else 
    something else
fi

Je peux exécuter une commande, par exemple darcs show repoet utiliser $?pour obtenir son code retour.

Ma question est la suivante: existe-t-il un moyen efficace d'exécuter et de renvoyer le numéro de code de retour sur une seule ligne? par exemple

if [ 0 -eq `darcs show repo`$? ]; 

Ou dois-je définir une fonction?

Une exigence supplémentaire est que stderr et stdout soient imprimés.

Niall Murphy
la source

Réponses:

15

Si vérifie automatiquement le code retour:

if (darcs show repo); then
  echo "repo exists"
else
  echo "repo does not exist"
fi

Vous pouvez également exécuter la commande et utiliser && (AND logique) ou || (OU logique) après pour vérifier si elle a réussi ou non:

darcs show repo && echo "repo exists"
darcs show repo || echo "repo does not exist"

Rediriger stdoutet stderrpeut être fait une fois avecexec

exec 6>&1
exec 7>&2
exec >/dev/null 2>&1

if (darcs show repo); then
  repo="darcs"
elif (test -d .git); then
  repo="git"
fi

# The user won't see this
echo "You can't see my $repo"

exec 1>&6 6>&-
exec 2>&7 7>&-

# The user will see this
echo "You have $repo installed"

Les deux premiers execenregistrent les descripteurs de fichiers stdinet stderr, le troisième redirige les deux vers /dev/null(ou ailleurs si vous le souhaitez). Les deux derniers execrestaurent à nouveau les descripteurs de fichiers. Tout le reste est redirigé vers nulle part.

Ajoutez d'autres chèques de pension comme l'a suggéré Gilles.

remuer
la source
Agréable et propre, cependant, ces méthodes impriment des messages à l'utilisateur. Je préférerais que le script soit silencieux (je l'ai ajouté à la question).
Niall Murphy
2
Pourquoi les utilisez-vous en sous-shell? C'est inutile.
Chris Down du
4

Comme d'autres l'ont déjà mentionné, if commandteste si elle commandréussit. En fait, [ … ]c'est une commande ordinaire, qui peut être utilisée en dehors d'une ifou whileconditionnelle bien qu'elle soit rare.

Cependant, pour cette application, je testerais l'existence des répertoires caractéristiques. Ce sera correct dans plus de cas marginaux. Version Bash / ksh / zsh / dash (non testé):

vc=
if [ -d .svn ]; then
  vc=svn
elif [ -d CVS ]; then
  vc=cvs
else
  d=$(pwd -P)
  while [ -n "$d" ]; do
    if [ -d "$d/.bzr" ]; then
      vc=bzr
    elif [ -d "$d/_darcs" ]; then
      vc=darcs
    elif [ -d "$d/.git" ]; then
      vc=git
    elif [ -d "$d/.hg" ]; then
      vc=hg
    fi
    if [ -n "$vc" ]; then break; fi
    d=${d%/*}
  done
fi
if [ -z "$vc" ]; then
  echo 1>&2 "This directory does not seem to be under version control."
  exit 2
fi
Gilles 'SO- arrête d'être méchant'
la source
2

Eh bien, ce n'est pas très joli, mais c'est une façon de le faire en ligne:

if darcs show repo > /dev/null 2>&1; then <do something>; fi

Par définition, if teste le code de sortie d'une commande, vous n'avez donc pas besoin de faire une comparaison explicite, sauf si vous voulez plus que le succès ou l'échec. Il existe probablement une façon plus élégante de procéder.

SethG
la source
0

Une autre option succincte serait:

[ -d .svn ] && { svn command 1; svn command 2; } 
Mihai Rotaru
la source