Como executo um comando e obtenho seu código de saída em menos caracteres?


13

Eu costumava escrever meus scripts assim:

some_command
while [ $? -ne 0 ] ; do
    sleep 1
    some_command
done

Sempre me irritava ter que escrever some_commandduas vezes. Posso colocá-lo dentro da seção de teste de loop de alguma forma?

Respostas:


20

Você pode usar some_commandcomo sua condição de teste.

while ! some_command; do sleep 1; done

A condição permanecerá verdadeira enquanto some_commandsair com um erro.

Ou uma maneira mais detalhada, se você quiser fazer verificações adicionais:

while ! some_command
do 
    # add more if desired
    sleep 1
done

Isso parece melhor do que o meu, mesmo que seja uma linha ;-) #
Anthon

O OP pode querer dividi-lo em várias linhas devem ele precisa para executar vários comandos em caso de falha, embora :)
John WH Smith

Não há razão para que você não possa quebrá-lo com ponto e vírgula para torná-lo com várias linhas.
Mark Stewart

1
... ou escrevawhile ! some_command; do several; commands; sleep 1; done
ignis

12

É para isso que serve o untilloop:

until some_command
do    sleep 1
done

É a negação lógica de um whileloop.

A especificação diz:

The untilLoop

  • O untilloop deve executar continuamente uma lista composta desde que outra lista composta tenha um status de saída diferente de zero.

  • O formato do loop até é o seguinte:

    até lista-composta-1
    faça lista-composta-2
    feito
  • A lista-composta-1 deve ser executada e, se tiver um status de saída zero, o untilcomando será concluído. Caso contrário, a lista composta 2 será executada e o processo se repetirá.

4

Você pode apenas fazer:

false
while [ $? -ne 0 ] ; do
   sleep 1
   some_command
done

isso tem a desvantagem de que ele sempre dorme um segundo primeiro

Se você deseja poder sair de um número de comandos para sair com 0, você pode:

while true; do
  if [ some_command ] ; then break ; fi
  if [ some_other_command ] ; then break ; fi
  sleep 1
done

o que, obviamente, também funciona por apenas some_command


5
O segundo exemplo não deve incluir [e ]contornar os comandos.
nyuszika7h

2

Nem while ! ...nem until ...trabalhos sobre os sistemas que congelou seu ambiente shell antes POSIX.1-2001. Isso, no entanto, faz.

while :; do
    if some command; then
        break
    fi
    sleep 1
done

Se você não precisa de portabilidade total, por que está escrevendo um script de shell? É mais provável que o Perl esteja disponível que o Bash.

sleep 1 while 0 != system qw(some command);

(Como acima, sleepo comando é executado apenas se o comando falhar.)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.