Como executar um comando Bash e executar duas instruções sobre falha?

5

Eu quero executar um comando Bash seguido por duas ações se e somente se o teste retornar um erro. Eu preferiria resolver essa tarefa como uma linha no Bash.

Aqui estão as duas formas que tentei:

ssh [email protected] "ls /home/somefile" || echo "File does not exist" && exit 1
ssh [email protected] "ls /home/somefile" || echo "File does not exist"; exit 1

O significado é o seguinte: Eu quero testar a existência de um arquivo em uma máquina remota (ou qualquer outra, apenas um exemplo), e no caso do primeiro comando retornar um erro, então - e somente então - os dois os seguintes comandos ( echo / exit ) devem ser executados. Os exemplos acima executam a instrução exit 1 independente do valor de retorno do comando ssh .

Como reescrever esta linha para que os comandos echo e exit sejam executados somente se o primeiro comando ( ssh ) falhar?

    
por Alex 27.01.2014 / 17:17

1 resposta

14
ssh [email protected] "ls /home/somefile" || { echo "File does not exist"; exit 1; }

Isso é chamado de comando composto. De man bash :

   Compound Commands
       A compound command is one of the following:

       (list) list  is  executed in a subshell environment (see COMMAND EXECU‐
              TION ENVIRONMENT below).  Variable assignments and builtin  com‐
              mands  that  affect  the  shell's  environment  do not remain in
              effect after the command completes.  The return  status  is  the
              exit status of list.

       { list; }
              list  is simply executed in the current shell environment.  list
              must be terminated with a newline or semicolon.  This  is  known
              as  a  group  command.   The return status is the exit status of
              list.  Note that unlike the metacharacters ( and ), { and }  are
              reserved words and must occur where a reserved word is permitted
              to be recognized.  Since they do not cause a  word  break,  they
              must  be  separated  from  list  by  whitespace or another shell
              metacharacter.

A sintaxe () provavelmente não funcionaria na sua situação porque os comandos seriam executados em um subshell e, em seguida, o exit apenas fecharia a subshell.

EDIT: para explicar a diferença entre os parênteses () e as chaves {} :

Os parênteses fazem com que os comandos contidos sejam executados em um subshell. Isso significa que outro processo de shell é gerado, o que avalia os comandos, e a questão exit in OP mataria essa sub-shell.

As chaves, por sua vez, fazem com que os comandos sejam avaliados no shell atual. Agora, o exit mata o shell atual, o que seria, por exemplo, preferível se você usar esta linha em um script de shell.

    
por 27.01.2014 / 17:22