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 / ubuntu / Perguntas / 1058498
Accepted
Pilot6
Pilot6
Asked: 2018-07-23 14:00:45 +0800 CST2018-07-23 14:00:45 +0800 CST 2018-07-23 14:00:45 +0800 CST

Como lidar sem goto no Bash?

  • 772

Bash não tem um operador goto. Tenho uma tarefa simples e não consigo descobrir como resolvê-la sem ir para ou adicionar um novo proc, e isso é indesejável.

Tenho duas condições e um bloco de código que deve funcionar assim:

[condição 1] se verdadeiro, execute alguns comandos e verifique [condição 2]; if false execute um bloco de código.

[ condição 2 ] se verdadeiro não execute o mesmo bloco de código; se false execute o mesmo bloco.

Tem solução, ou tenho que definir algum proc e usar exitaí? Usei um sinalizador var, mas não gostei.

Com goto disponível, ficaria assim:

[ cond 1 ] || goto label 1
  command
  ...
  command
  [ cond 2 ] && goto label 2

:label 1

block of code

:label 2

Algo parecido.

command-line bash
  • 3 3 respostas
  • 30983 Views

3 respostas

  • Voted
  1. Best Answer
    Sergiy Kolodyazhnyy
    2018-07-23T14:44:04+08:002018-07-23T14:44:04+08:00

    A maneira típica de trabalhar para usar ramificação em scripts de shell seria por meio de funções declaradas antes do bloco principal de código. No entanto, acho que o problema subjacente aqui é o lógico, e não o goto. Obviamente label 1é repetido, então isso pode viver como função. Mas também, a condição 2 pode ser transformada em uma função que também chama label 1por uma questão de legibilidade:

    #!/bin/bash
    
    label1(){
        echo "label 1 function"
    }
    
    check_cond2(){
        if ! [ condition2 ]; then
            label1 arg1 arg2
        fi
    }
    
    if [ condition1  ]; then
    
        command
        ...
        command
        check_cond2
    else 
        label1
    fi
    
    othercommand2
    othercommand3
    

    O que notei é que em ambas as condições você tem if false exec a block of codee if false exec a block of code, portanto, uma ideia seria começar verificando se essas condições são falsas. No entanto, fazer algo como if ! [ cond1 ] || ! [ cond2 ]mudaria a lógica de ramificação. Você ainda pode ver a versão em pseudocódigo disso ao ver o histórico de edição de postagens.

    • 14
  2. Fabby
    2018-08-30T14:20:16+08:002018-08-30T14:20:16+08:00

    Quando mudei do Windows para o Linux na minha área de trabalho, eu tinha muitos arquivos .BATe pré-existentes .CMDpara converter e não iria reescrever a lógica para eles, então encontrei uma maneira de fazer um gotoin bash que funciona porque o goto functioné executado sedem si mesmo para remover todas as partes do script que não devem ser executadas e, em seguida, avalia tudo.

    A fonte abaixo é ligeiramente modificada do original para torná-la mais robusta :

    #!/bin/bash
    
    # BAT / CMD goto function
    function goto
    {
        label=$1
        cmd=$(sed -n "/^:[[:blank:]][[:blank:]]*${label}/{:a;n;p;ba};" $0 | 
              grep -v ':$')
        eval "$cmd"
        exit
    }
    
    apt update
    
    # Just for the heck of it: how to create a variable where to jump to:
    start=${1:-"start"}
    goto "$start"
    
    : start
    goto_msg="Starting..."
    echo $goto_msg
    # Just jump to the label:
    goto "continue"
    
    : skipped
    goto_msg="This is skipped!"
    echo "$goto_msg"
    
    : continue
    goto_msg="Ended..."
    echo "$goto_msg"
    
    # following doesn't jump to apt update whereas original does
    goto update
    

    e não me sinto culpado de forma alguma, como Linus Torvalds disse:

    De: Linus Torvalds
    Assunto: Re: alguma chance de teste 2.6.0*?
    Data: Dom, 12 de janeiro de 2003 11:38:35 -0800 (PST)

    Acho que os goto's estão bem e geralmente são mais legíveis do que grandes quantidades de recuo. Isso é especialmente verdadeiro se o fluxo de código não for realmente recuado naturalmente (neste caso, é, então não acho que usar goto seja mais claro do que não, mas em geral goto pode ser muito bom para legibilidade).

    Claro, em linguagens estúpidas como Pascal, onde os rótulos não podem ser descritivos, os goto podem ser ruins. Mas isso não é culpa do goto, isso é dano cerebral do designer da linguagem.

    Fonte original do código (modificada para torná-la menos propensa a erros)
    A fonte da citação

    • 12
  3. Byte Commander
    2018-07-23T14:39:23+08:002018-07-23T14:39:23+08:00

    Você deve colocar o seu block_of_codeem uma função e usar algum if/else:

    my_function() {
        block of code
        ...
    }
    
    if [[ condition 1 ]] ; then
        command
        ...
        command
    
        if [[ ! condition 2 ]] ; then
            # label 1
            my_function
        fi
    
    else
        # label 1
        my_function
    fi
    
    # label 2    
    
    • 11

relate perguntas

Sidebar

Stats

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

    Existe um comando para listar todos os usuários? Também para adicionar, excluir, modificar usuários, no terminal?

    • 9 respostas
  • Marko Smith

    Como excluir um diretório não vazio no Terminal?

    • 4 respostas
  • Marko Smith

    Como descompactar um arquivo zip do Terminal?

    • 9 respostas
  • Marko Smith

    Como instalo um arquivo .deb por meio da linha de comando?

    • 11 respostas
  • Marko Smith

    Como instalo um arquivo .tar.gz (ou .tar.bz2)?

    • 14 respostas
  • Marko Smith

    Como listar todos os pacotes instalados

    • 24 respostas
  • Martin Hope
    Flimm Como posso usar o docker sem sudo? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    led-Zepp Como faço para salvar a saída do terminal em um arquivo? 2014-02-15 11:49:07 +0800 CST
  • Martin Hope
    ubuntu-nerd Como descompactar um arquivo zip do Terminal? 2011-12-11 20:37:54 +0800 CST
  • Martin Hope
    TheXed Como instalo um arquivo .deb por meio da linha de comando? 2011-05-07 09:40:28 +0800 CST
  • Martin Hope
    Ivan Como listar todos os pacotes instalados 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    David Barry Como determino o tamanho total de um diretório (pasta) na linha de comando? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher "Os seguintes pacotes foram retidos:" Por que e como resolvo isso? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford Como os PPAs podem ser removidos? 2010-07-30 01:09:42 +0800 CST

Hot tag

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

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