AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 676733
Accepted
Diagon
Diagon
Asked: 2021-11-10 03:55:47 +0800 CST2021-11-10 03:55:47 +0800 CST 2021-11-10 03:55:47 +0800 CST

Precisa do código de saída da função de condição quando um loop "while" do Bash termina

  • 772

Estou tentando obter o código de saída da função que estou chamando repetidamente na parte "condition" de um whileloop Bash:

while <function>; do 
    <stuff> 
done 

Quando esse loop termina devido a um erro, preciso do código de saída de <function>. Alguma ideia de como posso conseguir isso?

bash shell-script
  • 4 4 respostas
  • 2904 Views

4 respostas

  • Voted
  1. Best Answer
    roaima
    2021-11-10T04:30:47+08:002021-11-10T04:30:47+08:00

    Você pode capturar o valor de saída da condição e propagá-lo para frente:

    while rmdir FOO; ss=$?; [[ $ss -eq 0 ]]
    do
        echo in loop
    done
    echo "out of loop with ?=$? but ss=$ss"
    

    Resultado

    rmdir: failed to remove 'FOO': No such file or directory
    out of loop with ?=0 but ss=1
    

    Nesse caso, o status de saída de rmdir FOOfoi capturado na variável sse é 1. (Tente substituir rmdir FOOpor ( exit 4 ). Você descobrirá que ss=4.)

    Como é que isso funciona? Lembre-se de que a sintaxe é realmente while list-1; do list-2; done, e não a expectativa muito mais usual de while command; do list; done. O list-1pode ser uma sequência de comandos separados por ponto e vírgula, e a documentação afirma que o " whilecomando executa continuamente a lista list-2, desde que o último comando na lista list-1retorne um status de saída igual a zero " .

    Como uma apresentação alternativa da whilecondição de aparência confusa, é possível atribuir uma variável enquanto estiver dentro de uma expressão (( ... ))e, em seguida, usar o resultado. Isso fornece a estrutura de atribuição e teste mais difícil de ler, mas mais compacta:

    while rmdir FOO; ((! (ss=$?)))
    do
        echo in loop
    done
    echo "out of loop with ?=$? but ss=$ss"
    

    Alternativamente, você pode usar while rmdir FOO; ! (( ss=$? )). Eles funcionam porque ((1)) avalia aritmeticamente para 1, que geralmente é associado a true, e assim o código de saída dessa avaliação é 0 (sucesso). Por outro lado, ((0)) avalia aritmeticamente para 0, que geralmente está associado a falso, e assim o código de saída dessa avaliação é 1 (falha). Isso pode parecer confuso, pois afinal ambas as avaliações ((.))são "bem-sucedidas", mas este é um truque para trazer o valor das expressões aritméticas que representam verdadeiro/falso de acordo com os códigos de saída de sucesso/falha do bash e fazer expressões condicionais como if ...; then ...; fi, while ...; do ...; done, etc. , funcionam corretamente, seja com base em códigos de saída ou valores aritméticos.

    • 22
  2. AdminBee
    2021-11-10T04:00:01+08:002021-11-10T04:00:01+08:00

    Uma maneira de fazer isso é fazer o teste explicitamente em vez de delegá-lo ao while. Então, o seguinte deve fazer:

    err=0
    while true
    do
        <function>
        (( (err=$?) > 0 )) && break
        <stuff>
    done
    echo "$err"
    

    No início do loop (a priori infinito) você executaria o comando de condição "manualmente" e armazenaria o código de saída, verificaria e sairia do loop se for diferente de zero (indicando falha). Somente se for zero você executa o código de loop "real".

    A sintaxe pode ser "compactada" porque (como observado por @roaima) você pode ter atribuições de variáveis ​​dentro da (( ... ))construção de teste aritmético.

    • 5
  3. schrodingerscatcuriosity
    2021-11-10T04:52:45+08:002021-11-10T04:52:45+08:00

    Crie uma função de encapsulamento que defina uma variável com o resultado do código de saída de sua função. Exemplo:

    e=0
    
    # file does not exist
    foo() { 
      rm xyz
    }
    
    baz() { 
      foo
      e=$?
      [[ $e -ne 0 ]] && return 1
      return 0
    }
    
    # create a file
    touch xyz
    while baz; do
      # first loop succeeds, the file exists
      # second loop exits with error, file doesn't exists
      echo in loop
    done
    
    in loop
    rm: cannot remove 'xyz': No such file or directory
    
    # then
    $ echo $e
    1
    
    • 3
  4. Stéphane Chazelas
    2021-11-10T14:14:18+08:002021-11-10T14:14:18+08:00

    Com zsh, você pode usar returnde uma função anônima:

    () while ((1)) {
      <function> || return
      <stuff>
    }
    print $?
    

    Com qualquer shell do tipo Bourne, você sempre pode usar uma função nomeada:

    repeat_until_fail()
      while true; do
        <function> || return
        <stuff>
      done
    
    repeat_until_fail
    echo "$?"
    
    • 1

relate perguntas

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • MySQL Select com função IN () com array bash

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve