Если вы программировали в командой оболочке cmd в Windows, то вы, возможно, использовали оператор goto для того, чтобы выполнять различные блоки операторов. В bash нет оператора goto, и он, в общем, и не нужен. Однако, при переходе от cmd к bash может возникнуть вопрос, как же обойтись без goto в bash. Процесс выполнения скрипта в этих оболочках различается, тем не менее, можно написать в любой из них скрипт, который будет работать точно так же, как и скрипт в другой оболочке.
Пример 1: Несколько блоков, из которых должен выполниться только один.
Скрипт на cmd:
@echo off if %1 == 1 goto LABEL1 if %1 == 2 goto LABEL2 if %1 == 3 goto LABEL3 goto END :LABEL1 echo Parameter: 1 goto END :LABEL2 echo Parameter: 2 goto END :LABEL3 echo Parameter: 3 :END
Пример очень простой, между меткой и оператором goto может быть значительно большее количество команд, конечно же. И для операторов после LABEL3 переход нам не нужен, потому что и так уже достигнут конец скрипта.
Скрипт на bash:
#!/bin/bash label1(){ echo "Parameter: 1" } label2(){ echo "Parameter: 2" } label3(){ echo "Parameter: 3" } if [ "$1" == "1" ]; then label1; fi if [ "$1" == "2" ]; then label2; fi if [ "$1" == "3" ]; then label3; fi
В целом скрипты выполняются абсолютно идентичным способом. Различия вот в чем. В bash необходимо определить функцию до того, как она будет вызвана в первый раз. В cmd не используются функции, поэтому гибкость алгоритма обеспечивается непосредственными переходами при помощи goto на метку. Метка может быть в любом месте скрипта, как до команды перехода, так и после. В плане гибкости cmd имеет некоторое преимущество в том смысле, что метку можно вставить в любое место скрипта. Но bash с использованием функций позволяет сделать скрипт более строгим, более предсказуемым.
А в плане результата данный пример и в cmd, и в bash одинаков. Главное понять, что в cmd сам скрипт является целиком линейным, а в bash за счет возможности создания функций не является, так как сама функция представляется при ее вызове как обычная команда.
Пример 2: При соблюдении условия будет выполняться дополнительная часть команд.
Скрипт на cmd:
@echo off if %1 == 1 goto LABEL1 if %1 == 2 goto LABEL2 if %1 == 3 goto LABEL3 goto END :LABEL1 echo Parameter: 1 :LABEL2 echo Parameter: 1 or 2 goto END :LABEL3 echo Parameter: 3 :END
Получатся вложенный блок, который можно показательно выделить отступами
:LABEL1 echo Parameter: 1 :LABEL2 echo Parameter: 1 or 2 goto END
Такой вариант в bash будет выглядеть следующим образом:
#!/bin/bash label2(){ echo "Parameter: 1 or 2" } label1(){ echo "Parameter: 1" label2 } label3(){ echo "Parameter: 3" } if [ "$1" == "1" ]; then label1; fi if [ "$1" == "2" ]; then label2; fi if [ "$1" == "3" ]; then label3; fi
Вложенный блок выделяется в отдельную функцию label2, вызов которой осуществляется из label1. НО! Эта функция должна быть УЖЕ ОПРЕДЕЛЕНА к моменту первого вызова, поэтому в скрипте она должна находиться ВЫШЕ функции label1.
Имхо тогда уж лучше
case "$1" in
1) label1 ;;
2) label2 ;;
3) label3 ;;
esac
или уж
if [ "$1" == "1" ]; then label1;
elif [ "$1" == "2" ]; then label2;
elif [ "$1" == "3" ]; then label3;
fi
хотя первое, имхо, читабельнее
Тогда параллель будет не такая явная. В примере я хотел как раз показать практически идентичность основного логического блока. А вообще да, оптимизация наш друг.
Добрый день! а как сделать так что бы после выполнения функции выполнение скрипта продолжилось в цикле сорри за мою безграмотность))
напримере простого угадай число….
Добрый день. Как-то так:
Благодарю! вопрос зачем numb=-1 в начале?
Уже не нужна, можно удалить :-)