Script di Bash per rilevare il sistema di controllo versione testando lo stato di ritorno del comando


11

Sto lavorando a uno script bash che mi piacerebbe lavorare per diversi tipi di VCS. Sto pensando di verificare se una directory è un repository per un sistema eseguendo un tipico comando di informazioni e controllando il codice di ritorno, successo o errore. In pseudo codice:

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

Posso eseguire un comando, ad esempio darcs show repoe utilizzare $?per ottenere il suo codice di ritorno.

La mia domanda è: esiste un modo preciso per eseguire e restituire il numero del codice di ritorno in una riga? per esempio

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

O devo definire una funzione?

Un ulteriore requisito è che sia stderr che stdout debbano essere stampati.

Risposte:


15

Se controlla automaticamente il codice di ritorno:

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

Puoi anche eseguire il comando e usare && (AND logico) o || (OR logico) in seguito per verificare se è riuscito o meno:

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

Reindirizzamento stdoute stderrpuò essere fatto una volta conexec

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"

I primi due execstanno salvando i descrittori di file stdine stderr, il terzo reindirizza a /dev/null(o altrove se lo si desidera). Gli ultimi due execripristinano nuovamente i descrittori di file. Tutto nel mezzo viene reindirizzato verso il nulla.

Aggiungi altri controlli repo come suggerito da Gilles.


Bello e pulito, tuttavia questi metodi stampano i messaggi per l'utente. Preferirei che lo script fosse silenzioso (l'ho aggiunto alla domanda).
Niall Murphy,

2
Perché li esegui in una subshell? Non è necessario
Chris Down,

4

Come altri hanno già detto, if commandverifica se ha commandesito positivo. In realtà [ … ]è un comando ordinario, che può essere utilizzato al di fuori di ifo whilecondizionato sebbene sia raro.

Tuttavia, per questa applicazione, verificherei l'esistenza delle directory caratteristiche. Ciò sarà corretto in più casi limite. Versione Bash / ksh / zsh / dash (non testata):

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

2

Bene, non è molto carino, ma è un modo per farlo in linea:

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

Per definizione, se verifica il codice di uscita di un comando, quindi non è necessario eseguire un confronto esplicito, a meno che non si desideri qualcosa di più del successo o del fallimento. C'è probabilmente un modo più elegante per farlo.


0

Un'altra opzione concisa sarebbe:

[ -d .svn ] && { svn command 1; svn command 2; } 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.