Bash script para detectar el sistema de control de versiones probando el estado de retorno del comando

11

Estoy trabajando en un script bash que me gustaría trabajar para varios tipos de VCS. Estoy pensando en probar si un directorio es un repositorio para un sistema ejecutando un comando de información típico y verificando el código de retorno, el éxito o el error. En pseudocódigo:

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

Puedo ejecutar un comando, por ejemplo, darcs show repoy usarlo $?para obtener su código de retorno.

Mi pregunta es: ¿hay una forma ordenada de ejecutar y devolver el número del código de retorno en una línea? por ejemplo

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

¿O tengo que definir una función?

Un requisito adicional es que tanto stderr como stdout deben imprimirse.

Niall Murphy
fuente

Respuestas:

15

Si comprueba automáticamente el código de retorno:

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

También puede ejecutar el comando y usar && (AND lógico) o || (OR lógico) luego para verificar si tuvo éxito o no:

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

Redireccionamiento stdouty stderrse puede hacer una vez 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"

Los dos primeros execguardan los descriptores de archivo stdiny stderr, el tercero redirige a ambos /dev/null(o en otro lugar si lo desea). Los dos últimos execrestauran los descriptores de archivo nuevamente. Todo en el medio se redirige a ninguna parte.

Agregue otros controles de repositorio como sugirió Gilles.

meneo
fuente
Agradable y limpio, sin embargo, estos métodos imprimen mensajes al usuario. Preferiría que el script sea silencioso (he agregado esto a la pregunta).
Niall Murphy
2
¿Por qué estás ejecutando estos en una subshell? Es innecesario
Chris Down
4

Como otros ya han mencionado, if commandprueba si commandtiene éxito. De hecho, [ … ]es un comando ordinario, que puede usarse fuera de ifo whilecondicional, aunque es poco común.

Sin embargo, para esta aplicación, probaría la existencia de los directorios característicos. Esto será correcto en más casos extremos. Bash / ksh / zsh / dash versión (no probado):

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- deja de ser malvado'
fuente
2

Bueno, no es muy bonito, pero es una forma de hacerlo en línea:

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

Por definición, si prueba el código de salida de un comando, no necesita hacer una comparación explícita, a menos que desee algo más que éxito o fracaso. Probablemente haya una forma más elegante de hacer esto.

SethG
fuente
0

Otra opción sucinta sería:

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