LINUX.ORG.RU

Переход по функциям в bash

 , ,


0

1

Код скрипта https://savetext.ru/n29U9dgB

При запуске, скрипт выставляет дефолтные значения, после чего вызывает функцию beginning (строка 95), затем ждет минуту и переходит к циклу Starting (строка 130), в котором ожидает нажатия кнопки старта в течение 60 секунд. Если кнопка не была нажата, то вызывается функция halt, которая выставляет первоначальные значения и отключает питание внешних устройств через 30 секунд, а затем вызывает функцию first (строка 49) Функция first ожидает нажатия кнопки, после чего должна выполнить скрипт с вызова beginning (строка 95), но break лишь прерывает текущий цикл и возвращает скрипт к функции, вызванной до first. В идеале бы использовать какой-то аналог goto, для прерывания вызывающей функции и перехода к нужной, но в баше таковых нет.

Друзья, прошу помощи.


В идеале бы использовать какой-то аналог goto, для прерывания вызывающей функции и перехода к нужной

зачем?

return и циклов мало?

n_play
()
Ответ на: комментарий от n_play

Return и циклов вполне достаточно, но не затруднит ли вас показать решение на моем примере используя вышеупомянутое?

hs85
() автор топика

Ты смотришь на баш, как на ЯП. Он таковым не является.

При запуске, скрипт выставляет дефолтные значения, после чего вызывает функцию beginning (строка 95), затем ждет минуту

задержка необходима? в башике сначала отработает **функция beginning (строка 95), затем скрипт проспит минуту и

переходит к циклу Starting (строка 130), в котором ожидает нажатия кнопки старта в течение 60 секунд. Если кнопка не была нажата, то вызывается функция halt, которая выставляет первоначальные значения и отключает питание внешних устройств через 30 секунд, а затем вызывает функцию first (строка 49) Функция first ожидает нажатия кнопки, после чего должна выполнить скрипт с вызова beginning (строка 95), но break лишь прерывает текущий цикл и возвращает скрипт к функции, вызванной до first.

а так ты ещё и «перемешал» описание функций и сам скрипт…

Сам перепишешь или лениво? ;)

anonymous
()
Ответ на: комментарий от hs85

портянку на баше глядеть неохото. её проще выбросить.

давай начнешь с прототипирования. можешь даже на русском языке это делать.

покажи как ты видишь решение просто последовательностью вызовов функций (пусть они пока будут пустыми внутри, но надо знать что они делают - это в коментарии напиши к ним) и твоего решения на основе goto. т.е. алгоритм напиши

тогда будет ясно в чем там сложности. а заполнить туловища функций - потом уже сам сможешь.

вот смотри такой псевдокод например

1. поставить_дефолтные_значения // из описания понятно
2. выполнить_инициализацию // и подождать 
3. ожидать_нажатия_кнопки_60с
4. обработать_нажатие кнопки
5. условие ЕСЛИ нажатия не было то goto пункт 2
6. выключить_всё
7. выход

n_play
()
  1. Объявление переменных
  2. Выставление дефолтных значений
  3. Ожидание нажатия кнопки
  4. Если нажали, то включаем пин и ждем минуту
  5. После минуты ожидания, ждем еще одного нажатия кнопки в течение 5 минут.
  6. Если в течение 5 мнут кнопка так и не нажата, то возвращаемся к пункту 2
  7. Если за 5 минут кнопка была нажата, то переходим к пункту 8.
  8. Выполняем некоторый цикл. Если все условия выполнены, то
  9. Переходим в рабочий цикл, в котором так же проверяем нажатие кнопки. Если нажали, то возврат к пункту 2.
hs85
() автор топика
Последнее исправление: hs85 (всего исправлений: 1)
Ответ на: комментарий от hs85

а вот там уже понятнее.

7-8-9 оформить в отдельную функцию и смотреть код возврата.

все остальное 2-3-4-5-6 в бесконечный цикл

возврат к 2 - это continue в том бесконечном цикле.

примерно вот такую структуру сделать:

1. Объявление переменных

Функция DO_SOMETHING {
    Выполняем некоторый цикл. Если все условия выполнены, то
    Переходим в рабочий цикл, в котором так же проверяем нажатие кнопки. Если нажали, то return RETURN_CODE (где RETURN_CODE который ты будешь считать нажатием кнопки)
}

2. Тут бесконечный цикл {
    3. Выставление дефолтных значений
    4. Ожидание нажатия кнопки
    5. Если нажали, то включаем пин и ждем минуту
    6. После минуты ожидания, ждем еще одного нажатия кнопки в течение 5 минут.
    7. Если в течение 5 мнут кнопка так и не нажата, то возвращаемся к пункту 2 (т.е. вызываешь continue)
    8. Если за 5 минут кнопка была нажата, то вызываем функцию DO_SOMETHING.
    9. Проверяем код возврата из DO_SOMETHING (по нему определяем была ли нажата кнопка). Если она была нажата - то снова continue
}

как видишь, всё достаточно тривиально и никакой goto не нужен.

n_play
()
Ответ на: комментарий от n_play

Правильно ли я понимаю, что после вызова функции DO_SOMETHING (пункт 8), скрипт будет крутиться в этой самой функции до получения от нее return-кода?

hs85
() автор топика
Ответ на: комментарий от hs85

да.

как только в скрипте в процессе выполнения встретится вызов функции - то случится переход в её тело и покидание её по оператору return. с безусловным возвращение сразу же в то месте, которое следут после вызова функции.

скрипт будет крутиться в этой самой функции до получения от нее return-кода?

да, т.е. дальше скрипт продолжится. от пойдет в неё и будет выполнятся. там. при выходе из неё вернется к выполнении того на чем прервался (т.е. сразу того что после того вызова следует.

n_play
()
Последнее исправление: n_play (всего исправлений: 1)
Ответ на: комментарий от n_play

Видимо то, что нужно. Спасибо! Еще… А как обрабатывать коды return? Или же в функции достаточно того же break?

hs85
() автор топика
Последнее исправление: hs85 (всего исправлений: 1)
Ответ на: комментарий от hs85

break испоьзуется лишь для выхода из цикла.

допустим ты делаешь «return 11» в DO_SOMETHING если кнопка была нажата, тогда проверить это можно так

А как обрабатывать коды return?

они в специальную переменную $? заносятся

допустим где-то внутри цикла ты вызываешь

DO_SOMETHING

if [ $? == 11 ]
then
  continue
fi

а вообще, поищи, должно быть куча материала даже на русском языке по bash. и попробуй потренируйся, тогда быстрее поймешь и освоишь.

n_play
()
Ответ на: комментарий от n_play

Огромное спасибо! Похожий пример с return я видел, но не мог понять как работает. Теперь все понятно. Буду пробовать.

hs85
() автор топика
Ответ на: комментарий от hs85

Для простоты набросай работающий скелет (с пустыми функциями, просто выводи внутри функций сообщение через echo например, типа «я функция такая-то, делаю этовот»).

добейся нужного поведения, а потом заполняй функции. притом их тоже отладить и разработать отдельно от этого. а уже только потом собрать всё вместе.

иначе очень быстро получается каша.

и ещё я бы посоветовал включить остановку при ошибках и прочем. т.к. иначе он просто будет игнорировать неугодные ему строчки и работать дальше.

погугли: bash «set -e» и прочие штуки.

n_play
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.