Pull to refresh

Comments 19

первая ассоциация: троллейбус, но потом вспомнил свой велосипед для деплоя. В баше же есть массивы, в них нельзя хранить состояние автомата?
В данном случае, состояние — это некий выполняемый процесс, а вовсе не значения переменных.
Сохранение состояния можно делать при помощи trap. Если каждый шаг сам определяет следующий шаг, то основной цикл сильно упрощается:
trap 'echo STEP=$STEP > state' EXIT; while true; do ${STEP}; done
Код выше оформлен тегами pre, но что-то они не работают.
Только в простейшем случае для сохранения состояния достаточно сохранить шаг. В реальной ситуации придется сохранять еще и часть других переменных.

Не нашел в документации к trap ничего по поводу выполнения команды в trap в случае нормального завершения. Можете объяснить каким образом вы предполагаете нормальное завершение скрипта и как при этом будет сохранено его состояние?
Можно сохранить и несколько переменных, проблем нет.

Вот пример как работает trap EXIT:

$ cat 054-trap-test.sh
#!/bin/bash

trap 'echo done' EXIT
[ -z "$1" ] && echo no arg && exit
echo arg is $1
$ ./054-trap-test.sh
no arg
done
$ ./054-trap-test.sh 1
arg is 1
done
$

В случае нормального завершения скрипта можно сохранять первый шаг последовательности. Или пустое значение.
Попробовал. Да, действительно можно сделать выход в любой точке при помощи exit, а действие которое необходимо выполнить при завершении указать в trap.
Когда-то делал вот такой велосипед автомат:
ru.vingrad.com/Konechny-avtomat-s-dmumya-sostoyaniyami-na-bash-id53c397b2ae20154a6f023c30
С некоторой полезной нагрузкой.
Конечные автоматы, если мне не изменяет память, используются, например, в компиляторах для парсинга. Также, для разбора регулярных выражений.
Не изменяет, так и есть. А еще в играх. Но часто ли вам приходится писать синтаксические анализаторы? Я не утверждаю, что это бесполезная теория, как раз наоборот. Данный подход позволяет получить красивый структурированный код там, где при обычном были бы хитросплетения условий в которых даже их автор не смог бы разобраться уже на следующий день. Это одна из реализаций принципа «разделяй и властвуй» в программировании, в данном случае от помог разделить действия и условия переходов от одного к другому.
Я бы, наверное, сначала попробовал решить подобную задачу при помощи make. Конечных автоматов из коробки там нет, но не исключено, что процесс загрузки данных можно представить в виде DAG, и тогда make очень даже неплох.
Шаги можно только пропускать. Осознав проблему код был переписан
if [[ условие ]]
then
    STEP='step2'
else
    STEP='step3'
fi

если я правильно понимаю, то если переходить можно только в два состояния, то можно и просто пропускать: при невыполнении условия переходить к следующему шагу, поскольку нумерация шагов условная
В реальном скрипте шаги не нумерованные а именованные. В сколько состояний можно переходить заранее неизвестно. Пропустить шаг, конечно, можно по условию, но если так делать то по мере совершенствования скрипта и увеличению всевозможных условий переходов получиться паутина из IF-ов. Конечные автоматы как раз позволяют этого избежать. В своем скрипте, в результате такого подхода, я смог спокойно менять условия переходов не запутываясь в условиях, к тому же последовательность «шагов» также не фиксирована.
UFO just landed and posted this here
Выйдя в понедельник на роботу и еще немного поразмыслив я понял, что код можно еще немного улучшить избавившись от case. Код смотрите в конце статьи.
В данном случае в нем нет необходимости, но если захотите сохранить еще что-нибудь…
Для этого и показал как сделать перевод строки.
Здесь лучше подойдёт не echo, а printf:

printf 'STEP=%q\nOTHER_VAR=%q\n' "$STEP" "$OTHER_VAR"


Вы же не хотите долго отлаживать скрипт, если вам внезапно придёт в голову сохранение значения вида "abc\\ndef"?
Спасибо, внес правку в последний вариант скрипта.
А кстати, главный процесс в linux — init — не является ли конечным автоматом?
Sign up to leave a comment.

Articles