Resolve o script bash sem goto

1

Eu tenho um script que eu quero fazer algo como

read one_thing
read another_thing

E, em seguida, ele executa algum código para ver se another_thing está disponível ou já está sendo usado e, se for usado, deverá avisar o usuário e executar novamente

read another_thing

para que possamos ter um novo valor, deixando one_thing sem perturbação. Como não há goto no bash, estou imaginando como fazer isso. Meu melhor palpite até agora é que talvez eu devesse embrulhar read another_thing dentro de uma função, de modo que, se necessário, ela fosse chamada, mas acho que deve haver uma maneira “limpa” de fazê-lo. Estou à procura de sugestões sobre maneiras eficientes de fazer isso.

    
por user137369 07.01.2013 / 18:54

2 respostas

2

Você pode verificar sua condição em um loop e break dela quando ela é cumprida.

#!/bin/bash

read -p 'Input something > ' one_thing

while true; do
  read -p 'Input something else > ' another_thing

  # Write some code to check if the requirements are met
  # Let's say in this case they are when the variable 'thing_to_work' equals 'done'

  if [[ "${thing_to_work}" == 'abcde' ]]; then
    break # Exit the loop
  else
    echo 'The requirements were not met, so the loop will start again'
  fi
done
    
por 07.01.2013 / 21:22
1

Quando mudei do Windows para o Linux na minha área de trabalho, eu tinha muitos arquivos .BAT e .CMD pré-existentes para converter e eu não ia reescrever a lógica para eles, então eu encontrado uma maneira de fazer um goto no bash que funciona porque a função goto executa sed em si mesma para remover todas as partes do script que não devem ser executadas e, em seguida, avaliar tudo:

#!/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 eu não me sinto culpado como Linus Torvalds disse de maneira famosa:

From: Linus Torvalds
Subject: Re: any chance of 2.6.0-test*?
Date: Sun, 12 Jan 2003 11:38:35 -0800 (PST)

I think goto's are fine, and they are often more readable than large amounts of indentation. That's especially true if the code flow isn't actually naturally indented (in this case it is, so I don't think using goto is in any way clearer than not, but in general goto's can be quite good for readability).

Of course, in stupid languages like Pascal, where labels cannot be descriptive, goto's can be bad. But that's not the fault of the goto, that's the braindamage of the language designer.

Fonte para código (modificada para torná-la menos propensa a erros)
< a href="http://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/"> Fonte para cotação

    
por 30.08.2018 / 00:44

Tags