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
Что-то как этот.
Типичный способ работать для использования ветвления в сценариях оболочки был бы через функции, объявленные перед основным блоком кода. Однако я думаю, что базовой проблемой здесь является логическая единица а не 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 ]
изменил бы переходящую логику. Можно все еще видеть псевдоверсию кода этого путем наблюдения, что это отправляет историю редактирования.
Необходимо поместить Ваш 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
Когда я переместился от 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, это - повреждение мозга разработчика языка.
Первоисточник для кода (измененный для создания этого менее подверженным ошибкам)
Источник для кавычки