направляет данные в демонизированный не демон, используя команды оболочки - PullRequest
1 голос
/ 21 января 2011

Это то, что я хочу сделать:

$ serverise normally-barely-interactive-program-that-uses stdin stdout &<br> unique-id-221B $ clienty 221B "Astonishing!"<br> Elementary<br> $ clienty 221B "what did I just say?"<br> 'Astonishing', although the methods are simple and easily followed, once explained.<br> $ clienty 221B "so, you persist between invokations of the client?"<br> Indeed.

Я пробовал двойные именованные каналы, но они только для последнего вызова.Я думаю, это потому, что серверная сторона получает EOF и поэтому предполагает, что stdin был закрыт пользователем.

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

Я видел, как для этого использовались Gnu Screen и Tmux, но это кажется излишним, и, честно говоря, я не могу предположить, что среда пользователя выигралане содержит ни того, ни другого, и поэтому любое подобное решение было бы немного хрупким перед лицом нестандартных конфигов тех.Это также кажется немного излишним.

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

Ответы [ 2 ]

0 голосов
/ 21 января 2011

Относительно вашей проблемы с именованными каналами только для одного вызова: если это действительно ваша единственная проблема, ее легко обойти. (мой пример едва интерактивной программы: bc)

$ mkfifo in out
$ while read line <in; do echo "$line"; done | bc >out &
$ cat out &
$ echo "1+1" >in
2
$ echo "2+2" >in
4

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

Обратите внимание, что:

  • вход ограничен линией за раз
  • выходной поток имеет ту же проблему: его нужно открывать только один раз
0 голосов
/ 21 января 2011

Это невозможно в описываемом вами общем случае.

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

В вашем примере рассмотрим ваш первый clienty вызов. Очевидно, что запрос «Удивительно» может быть напрямую передан на стандартный сервер, и кажется, что сервер пишет «Элементарный» в своем стандартном выводе. Но что тогда? Должна ли оболочка перенести это немедленно? Буфер это? Как он узнает, является ли ответ полным? Предполагая, что вы решили, что, если несколько клиентов запрашивают одновременно, как он узнает, на какой ответ отправить ответ?

Вам нужен минимальный объем протокола, чтобы решить это. Это может быть так просто, как «ответы однострочные, гарантированные и упорядоченные».

...