Script Bash para detectar o sistema de controle de versão testando o status de retorno do comando

11

Estou trabalhando em um script bash que gostaria de trabalhar para vários tipos de VCS. Estou pensando em testar se um diretório é um repositório para um sistema executando um comando info típico e verificando o código de retorno, êxito ou erro. No pseudo-có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

Eu posso executar um comando, por exemplo, darcs show repoe usar $?para obter seu código de retorno.

Minha pergunta é: existe uma maneira elegante de executar e retornar o número do código de retorno em uma linha? por exemplo

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

Ou tenho que definir uma função?

Um requisito adicional é que stderr e stdout sejam impressos.

Niall Murphy
fonte

Respostas:

15

Se verificar automaticamente o código de retorno:

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

Você também pode executar o comando e usar && (AND lógico) ou || (OR lógico) posteriormente para verificar se foi bem-sucedido ou não:

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

Redirecionando stdoute stderrpode ser feito uma vez comexec

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"

Os dois primeiros execestão salvando os descritores de arquivo stdine stderr, o terceiro redireciona os dois para /dev/null(ou outro lugar, se desejado). Os dois últimos execrestauram os descritores de arquivo novamente. Tudo no meio é redirecionado para lugar nenhum.

Anexe outras verificações de repo como Gilles sugeriu.

abanar
fonte
Agradável e limpo, no entanto, esses métodos imprimem mensagens para o usuário. Eu preferiria que o script fosse silencioso (eu adicionei isso à pergunta).
Niall Murphy
2
Por que você os está executando em um subshell? Isso é desnecessário.
Chris Baixo
4

Como outros já mencionaram, if commandtesta se commandé bem-sucedido. De fato, [ … ]é um comando comum, que pode ser usado fora de ifou whilecondicional, embora seja incomum.

No entanto, para esse aplicativo, eu testaria a existência dos diretórios de características. Isso estará correto em mais casos extremos. Versão Bash / ksh / zsh / dash (não testada):

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- parar de ser mau'
fonte
2

Bem, não é muito bonito, mas é uma maneira de fazer isso em linha:

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

Por definição, se testar o código de saída de um comando, não será necessário fazer uma comparação explícita, a menos que você queira mais do que sucesso ou falha. Provavelmente existe uma maneira mais elegante de fazer isso.

SethG
fonte
0

Outra opção sucinta seria:

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