LINUX.ORG.RU

Прерывание и восстановление питон-скрипта в шелле. (то же для си).

 , , ,


1

2

Дано: код пишется частично на bash, частично на python. «Запускающую» роль имеет питон, ибо рулить им слегка проще.

Получается этакий «питон со вставками на bash». Bash там нужен в основном затем, чтобы прямо в терминале наблюдать красивый вывод из гнушных системных утилит (н-р internal compiler error в GCC - достаточно важная штука, чтобы его выхлоп можно было посмотреть сразу и красиво:).

Сейчас это как-то работает, но скверно, недобро, это даже не фигота, а нездоровая китайская эриоботрия.

(Аналогичная ситуация есть для си и крестов, «си с башевыми вставками», но пока не стоит остро, предложения по прерывания c/c++ тоже было бы интересно. C++ с классами и шаблонами, C «чистый от скверны» - т.е. сам си, без автосгенеренного кода).

(среда, если это важно: стандартная ситуация для Linux/MacOSX: обязательное наличие GNU bash 3.2.51+, perl 5.12+, python 3.4+, и основных утилит GNU (желательно, без злоупотреблений, н-р на системе со старым getopt (MacOSX) не кошерно просить новый getopt (Linux), но в общем можно потребовать любые популярные утилиты, даже новый getopt))

Допустим, у нас алгоритм записан так: Питон->Баш->Баш->Питон. Нужно реализовать эту цепочку.

1) нужно прервать выполнение питон-скрипта, собрать важные переменные-контекст и выплюнуть все это в баш. С прерыванием непосредственно питоновского скрипта, т.е. очень желательно, чтобы новый баш не был чайлдом, а был сиблингом с точки зрения запускающего шелла. Как это сделать правильно? («Ты дебил»/«не гуглил» итэпэ - черт возьми, сделать это можно тысячью способов, вопрос в том, какой из них расово верный для линукса).

2) Теперь, башевый скрипт закончился и мы хотим вернуться назад в питон и восстановить состояние до той точки, откуда начинали. Тут возинкают два вопроса: а) методика сохранения состояния между перезапусками, которая позволяла бы писать как можно меньше boilerblate на сохранение состояния и б) методика грубо говоря осуществления goto, поиска нужной точки кода, где сохраненное состояние имеет смысл. Мы не можем сделать goto на произвольную часть кода, соответственно его нужно как-то специальным образом организовать.

Ну и раз уж здесь ЛОР, то

3) Как мне сделать то что я хочу, а не то, что я попросил? :3

Идея не рекурсивного запуска, а замены сиблингом - ногами из эпохи печатных терминалов. Т.е. мы имеем некую бумагу, в которой пробиваем дырки, мы не можем рекурсивно вызвать из бумаги бумагу.

Идея прерывания с адресом возврата ногами еще из ассемблера, когда мы кладем адрес возврата и прыгаем в сабрутину. Сабрутина может быть на чем угодно написана, лишь бы адрес возврата никуда не девался. Но в асме у нас как бы есть физическое «общее состояние», а запуская из питона баш каково общее состояние? Переменные окружения? Файл? Да и вообще, как-то довольно убого писать в «плоском» стиле на питоне. Из кода получится не лапша, а даже что-то хуже, т.к. количество уровней вложенности строго ограничено кодом обработки «файлов»-«регистров».

Может быть все это давным-давно устарело, и его небоходимо выбросить на свалку. С другой стороны, представляете, как это няшно: когда можно работать в голом терминале, н-р сидя на одном-единственном коннекте до целевого сервака в путти или айтерме, и все работает. Разве оно не стоит того?

★★★★☆

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

Откуда это требование?

У тебя по всему описанию по смыслу получается дочерний процесс.

alpha ★★★★★
()

Мсье знает толк в извращениях

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

Даже если дочерний процесс, какой кусок кода на питоне _устойчиво_ перехватывает ввод-вывод настолько, чтобы результат был неотличим от терминала? Там не просто текст, а псевдографика.

В яве какая-то либа была - куча всего написана, на хэлловорлде работает, но как конпелятор выплюнет в stderr два мегабайта запятых, так что у буферов оверфлоу - так сразу кровь-кишки-расчлененка. Пришлось вписывать в кишки еще мегабайт кода, ждущего буферы, но после этого все стало тормозить как слайдшоу. С тех пор очень подозрительно отношусь ко всяким перехватчикам ввода-вывода

Я сейчас буду (от безысходности) прикручивать pexpect как «дочерний терминал», но это же фигня полная! Насколько я помню несколько лет назад, например, если после .interact вызвать mc, на экране вместо mc оказываются кровь, кишки и расчлененка, ничего не знающая о настройках конкретного терминала.

Вроде бы под явой был какой-то встраиваемый эмулятор терминала, так что можно из питона вызвать яву, а из явы этот эмулятор терминала, но это жеж какая ж содомия получается! Написавший это на износилование гомосексуалом не жалуется!

Ну или вообще питон заменить явой, но это вообще печально, т.к. нужны именно скрипты. Под явой есть скрипты - встроенный движок жаваскрипта Рино, но это очередная содомия выходит.

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

какой кусок кода на питоне _устойчиво_ перехватывает ввод-вывод настолько, чтобы результат был неотличим от терминала?

Так это же не вопрос перехвата, а вопрос обработки данных которые ты перехватил. Перехватывает вон subprocess, только что ты с ними дальше-то делать будешь?

Ну то есть, чтобы всё выглядело как терминал — надо написать эту программу-терминал.

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

Я жду, что ее уже кто-то написал, и есть магическая ссылка на нее =)

Полностью блокирующий перехват не нужен. В основном нужно просто выступать прослойкой, которая тихо себе живет где-то, и вмешивается только когда надо. В общем, expect, только не pexpect, а полноценный эмулятор терминала.

Это если предпологать твою концепцию про подпроцессы.

Можно просто сгенерить питоном скрипт на баше, и потом выйти из питона. Шелл поймает SIGCHLD (или что там, не шарю), проверит и запустит переменную окружения $NEXT (в которой записан адрес до сгенерированного баш-скрипта), запустит его, опять поймает SIGCHLD, проверит и запустит переменную окружения $RET (в которой записан путь до вызывающего питон-скрипта), вызывающий питон-скрипт прочитает файл /tmp/12345/state и вернется goto до точки прерывания. Но тогда как раз возинкает вопрос с сохранением не только данных, но и позиции в коде.

stevejobs ★★★★☆
() автор топика

Все, дошло. Как от жопы динозавра до головы шло, два года. Надо сделать еще один уровень: питон запускает внутри себя блоки и процессы на питоне, и subprocess'ом рождает баш. Тогда хранить shared state и адреса возврата можно прямо внутри «главного питона», не заморачиваясь на переменные окружения. А если блок захардкожен прямо в «главный питон», то вызовы баша можно вообще сделать велосипедными промисами и в результате получится красивый код как раз в стиле «extern Bash» :3

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

Ну да. Ты же описываешь стандартную процедуру вызова функций: сохранение контекста, передача выполнения в функцию, возврат и восстановление контекста. Для этого не надо останавливать процесс и как-то над ним издеваться.

промисами

А можно перевод для чайников?

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

Все-таки обязательно, наверное. Ведь код на баше или на питоне может в любое время рухнуть, и надо дать возможность пользователю что-то сделать с этим фрагментом: перезапустить, вернуться к предыдущему и поправить настройки генерации, итп. Чем больше изоляция, тем лучше. А в линуксе разве есть какая-то изоляция кроме как на уровне процессов?

Т.е. все равно из-под питона запускать отдельными процессами питон и баш, просто shared state шарить внутри главного питона удобней, чем в переменных окружения и файлах. С другой стороны, если упадет главный питон, state просрется весь, а с файлами такого не было бы(

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 1)

Саааанииииитаааааррыыыыы

MikeDM ★★★★★
()
Ответ на: комментарий от tailgunner

Там скучно, я лучше на педоне поговнокожу

stevejobs ★★★★☆
() автор топика

Чем os.system() не устраивает?

NeXTSTEP ★★
()
Ответ на: комментарий от Pa

ключевое слово - «зарелизился». Взял, внезапно, из пакетного менеджера, «sudo port install python34 && port select python 3.4». Если у вас в пакетном менеджере нету, можете пройти сюда, клонировать исходники самой последней ревизии какую найдете, и собрать в отдельном префиксе.

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

Что не так?

То, что python 3.4+ - это не стандартная ситуация. Ну и то, что обдолбанных вроде тебя нужно запирать в толксах.

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

Ты не поверишь, в моем скрипте менеджер зависимостей работает не только на других, но и на себя тоже, так что одной строчкой можно потребовать наличия питона 3.4 - он сам скачает его из репозитория меркуриалом и скомпилирует в отдельном префиксе, после чего перезапустит скрипт с той точки, когда потребовался питон 3.4. Т.е достаточно иметь хоть какой-нибудь питон 3 чтобы запустился install_base_deps, который забутстрапит то, что нужно. Лол. Такие-то как раз вещи вообще не проблема, когда известно что исходник сто пудов соберется. Проблема когда не собирается и нужно парсить выхлоп компилятора.

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

Ты не поверишь, в моем скрипте менеджер зависимостей

Как раз поверю. Сразу и безоговорочно. Точно так же, как поверю, что фраза «стандартная ситуация» имеет для тебя какой-то глубоко личный смысл.

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

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

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

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

Хе-хе, последний раз жалобы на «нужный глибец» я слышал во времена, когда и центоса-то никакого не было, а редхатовцы только-только сменили libc.5 на libc.6

Но даже и это не проблема, chroot в виртуальный рут решает.

Проблема - как раз в уровне извращений. Питон как хранитель состояния и средоточие бытия - это сильно. Ящетаю, тут не меньше, чем сдвиг парадигмы и новая операционная система на подходе.

AlexM ★★★★★
()

Тебе помогут named pipes.

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