it-swarm-es.com

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

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, p. Ej. darcs show repo y use $? para obtener su código de retorno.

Mi pregunta es: ¿hay una forma ordenada de ejecutar y devolver el número de 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.

11
Niall Murphy

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"

Redirigir stdout y stderr se puede hacer una vez con exec

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 exec están guardando los descriptores de archivo stdin y stderr, el tercero redirecciona ambos a /dev/null (o en algún otro lugar si se desea). Los dos últimos exec restauran de nuevo los descriptores de archivo. Todo lo que hay en el medio se redirige a ninguna parte.

Agregue otras comprobaciones de repositorio como sugirió Gilles.

15
wag

Como ya han mencionado otros, if command comprueba si command tiene éxito. De hecho [ … ] es un comando ordinario, que se puede usar fuera de un condicional if o while aunque no es común.

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

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

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.

2
SethG

Otra opción sucinta sería:

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