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 / 423699
Accepted
Ole Tange
Ole Tange
Asked: 2018-02-13 12:55:01 +0800 CST2018-02-13 12:55:01 +0800 CST 2018-02-13 12:55:01 +0800 CST

Bash: Maneira elegante de definir status? [fechado]

  • 772
Fechado . Esta questão precisa de detalhes ou clareza . Atualmente não está aceitando respostas.

Quer melhorar esta questão? Adicione detalhes e esclareça o problema editando esta postagem .

Fechado há 4 anos .

Melhore esta questão
  • true && echo foovai imprimir foo.
  • false && echo foonão imprimirá foo.
  • bash -c "exit $a" && echo fooserá impresso foodependendo de $a.

Existe uma maneira mais elegante de escrever o último? Parece um pouco demais ter que iniciar um shell simplesmente para definir o valor de saída. Estou pensando em algo como:

  • return $a && echo foo
  • exit $a && echo foo

exceto returnfunciona apenas em funções e exitfará com que echo foonunca seja executado.

Elegante neste contexto significa:

  • Fácil de entender
  • Portátil
  • Fácil de ler
  • fácil de escrever
  • Fácil de lembrar
  • Curto
  • Alta performance

Por exemplo, se truepegasse o código de saída como um argumento (e este era um recurso documentado), seria muito elegante.

Então, existe uma maneira mais elegante?

Fundo

Um dos lugares que isso pode ser usado é para:

$ parallel 'setexitval {= $_%=3 =} || echo $?' ::: 0 1 2 3  

A versão de Kusalananda é provavelmente a melhor. Está claro o que está acontecendo. Não é longo e complicado de escrever. É fácil de lembrar e portátil. A única desvantagem é que ele bifurca outro shell (custa ~ 0,5 ms):

$ parallel '(exit {= $_%=3 =}) || echo $?' ::: 0 1 2 3  

Outra situação é quando você deseja simular uma condição de erro. Digamos, se você tiver um programa de execução longa, que define diferentes códigos de saída e estiver escrevendo algo que reagirá aos diferentes códigos de saída. Em vez de ter que executar o programa de execução longa, você pode usar (exit $a)para simular a condição.

bash exit-status
  • 4 4 respostas
  • 5705 Views

4 respostas

  • Voted
  1. ilkkachu
    2018-02-13T13:33:28+08:002018-02-13T13:33:28+08:00

    Bem, returnfunciona em uma função, então vamos fazer uma:

    $ ret() { return "${1-0}"; }
    $ ret 1 || echo foo
    foo
    $ ret 123 ; echo $?
    123
    

    Ele precisa de um pouco mais de configuração do que um subshell, mas é mais curto para usar depois disso e não requer a bifurcação de um subshell.

    • 13
  2. Best Answer
    Kusalananda
    2018-02-13T13:19:35+08:002018-02-13T13:19:35+08:00

    Use um subshell que sai com o valor especificado.

    Isso produzirá 5:

    a=5; ( exit $a ) && echo foo; echo $?
    

    Isso produzirá fooe 0(observe, esse zero é definido por echosucesso, não por exitno subshell):

    a=0; ( exit $a ) && echo foo; echo $?
    

    Em sua forma abreviada (sem configurar visivelmente aou investigar $?explicitamente):

    ( exit $a ) && echo foo
    

    Minha resposta é aquela que vem de apenas pegar a questão pelo valor de face e resolvê-la como um questionário curioso, "como podemos definir $?(usando notação útil)". Não tento buscar nenhum significado ou função mais profunda ou mesmo contexto neste caso (porque não foi dado). Além disso, não julgo a validade, eficiência ou usabilidade da solução. Às vezes, em minhas respostas, digo coisas como "... mas não faça isso, porque ...", seguido de "em vez disso, faça isso ...". Nesse caso, estou optando por interpretar a pergunta simplesmente como um questionário curioso.


    Mais antecedentes foram adicionados à pergunta.

    Minha opinião sobre a questão de bifurcar um subshell é que scripts como o GNU configurefazem isso o tempo todo e que não é muito lento, a menos que seja feito em um loop realmente apertado (de longa duração).

    Não posso dizer muito sobre o uso disso no/com o GNU parallel, pois não sou um usuário frequente desse software.

    • 8
  3. Ole Tange
    2018-02-13T12:58:26+08:002018-02-13T12:58:26+08:00

    Uma opção (provavelmente mais rápida, mas não muito mais elegante):

    test "$a" -eq 0 && echo foo
    

    Ele executa echo, mas não define o valor de saída como $a, portanto, é uma solução medíocre.

    • 5
  4. Sergiy Kolodyazhnyy
    2018-02-13T14:22:38+08:002018-02-13T14:22:38+08:00

    Vamos examinar suas suposições:

    • true && echo fooimprimirá foo. Correto porque &&adere a AND com lógica de curto-circuito; devido à associatividade à esquerda nos operadores &&e ||se o comando mais à esquerda retornar o status de saída com sucesso 0 (o que truesempre ocorre), o comando mais à direita para esse operador será executado.

    • false && echo foonão imprimirá foo. Exatamente o caso oposto do explicado acima.

    • bash -c "exit $a" && echo fooimprimirá foo dependendo de $a. Suposição essencialmente errada que $acontrola &&. Por && ser lógica AND, ele reconhece apenas dois estados - sucesso ou falha, onde falha é qualquer status de saída acima de 0. Assim exit 1, e exit 2e exit 3- todos são irrelevantes para &&; falha é falha independentemente do $avalor; é por isso echo fooque não funciona.

    Portanto, a resposta é não, não há maneira mais elegante de fazer algo que opere sob suposições erradas de qualquer maneira. No entanto, se o seu objetivo é definir o status de saída por meio do comando, basta usar o que a resposta de Kusalananda sugere - um subshell. Pessoalmente, não vejo nada diferente da bash -cparte, exceto que o subshell pode ser implementado como processo filho/processo bifurcado em vez de processo separado; ainda não é o ideal. Observe que $?também não deve ser definido pelo usuário por meio de variável - destina-se a comandos para comunicar sucesso ou falha.

    Vamos mudar o foco $apor um segundo. Por que definir $?e echo foo, se você pode verificar diretamente $a? Não faz sentido colocar o $avalor onde ele não pertence de qualquer maneira, ou seja, em $?. Eu recomendaria mudar o foco de "elegante" (o que quer que isso signifique) para "lógico" e "funcional".


    Tudo bem, mas vamos jogar o seu jogo. Tomando uma modesta inspiração da resposta de ilkkachu . Essa abordagem, no entanto, remove a necessidade de forçar a execução condicional de eco. Irá ecoar apenas se uma variável fornecida indicar sucesso e returnimpedir sua execução.

    $ thing(){ [ "${1-0}" -eq 0 ] || return "$1" ; echo "foo"; }
    $ thing
    foo
    $ thing 0
    foo
    $ thing 1
    $ echo $?
    1
    $ thing 2
    $ echo $?
    2
    

    O que pode não ser óbvio é que você pode fazerthing $a

    • 4

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

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

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

  • 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

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

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 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

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 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
    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
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +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
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +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