Как иметь дело без goto с Bash?

Bash не имеет goto оператора. У меня есть простая задача, и я не могу выяснить, как решить ее без goto или добавления нового proc, и это нежелательно.

У меня есть два условия и блок кода, который должен проложить себе путь:

[условие 1], если истинное выполнение некоторые команды и проверка [условие 2]; если ложное должностное лицо блок кода.

[условие 2], если верный не делает должностного лица тот же блок кода; если ложь действительно выполняет тот же блок.

Действительно ли это разрешимо, или я должен определить некоторый proc и использование exit там? Я использовал var флага, но мне не нравится он.

С goto, доступным, это посмотрело бы этот путь:

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

:label 1

block of code

:label 2

Что-то как этот.

4
задан 23 July 2018 в 10:10

3 ответа

Типичный способ работать для использования ветвления в сценариях оболочки был бы через функции, объявленные перед основным блоком кода. Однако я думаю, что базовой проблемой здесь является логическая единица а не goto. Очевидно, label 1 повторяется, таким образом, это может жить как функция. Но также и, условие 2 могло быть превращено в функцию, которая также звонит label 1 ради удобочитаемости:

#!/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

То, что я заметил, - то, что в обоих условиях Вы имеете if false exec a block of code и if false exec a block of code, таким образом, одна идея состояла бы в том, чтобы запуститься при проверке ли те условия обе лжи. Однако создание чего-то как if ! [ cond1 ] || ! [ cond2 ] изменил бы переходящую логику. Можно все еще видеть псевдоверсию кода этого путем наблюдения, что это отправляет историю редактирования.

10
ответ дан 23 November 2019 в 11:34

Необходимо поместить Ваш block_of_code в функцию и использование некоторые, если/еще:

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    
10
ответ дан 23 November 2019 в 11:34

Когда я переместился от Windows до Linux на моем рабочем столе, у меня было большое существование ранее .BAT и .CMD файлы для преобразования и я не собирался переписывать логику для них, таким образом, я нашел способ сделать a goto в ударе, который работает потому что goto function выполнения sed на себе для разделения любых частей сценария, который не должен работать, и затем evals все это:

#!/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

и я не чувствую себя виновным вообще, как заметно сказал Linus Torvalds:

От: Linus Torvalds
Тема: Ре: шанс с 2.6.0 тестами*?
Дата: Sun, 12 января 2003 11:38:35 - 8:00 (PST)

Я думаю, что goto's прекрасен, и они часто более читаемы, чем большой объем добавления отступа. Это особенно верно, если поток кода на самом деле естественно не располагается с отступом (в этом случае, это, таким образом, я не думаю с помощью goto, всегда более ясно, чем не, но в общем goto's может быть довольно хорошо для удобочитаемости).

Конечно, на глупых языках как Паскаль, где маркировки не могут быть описательными, goto's может быть плохим. Но это не отказ goto, это - повреждение мозга разработчика языка.

Первоисточник для кода (измененный для создания этого менее подверженным ошибкам)
Источник для кавычки

8
ответ дан 23 November 2019 в 11:34

Другие вопросы по тегам:

Похожие вопросы: