У меня есть проблема: у меня есть одна программа, работающая в оболочке, которая выполняет некоторые вычисления на основе пользовательского ввода, и я могу запустить эту программу в интерактивном режиме, чтобы она продолжала запрашивать ввод и выводила свои вычисления послепользователь нажимает ввод.Поэтому он остается открытым внутри оболочки до тех пор, пока пользователь не введет слово выхода.
Что я хочу сделать, это создать интерфейс таким образом, чтобы пользователь мог вводить ввод в другом месте вне оболочки и использовать pipe,fifo и т. д. ввод данных переносится в эту программу, а вывод - в этот интерфейс.
В двух словах: у меня длительный процесс, и при необходимости мне нужно подключить мой интерфейс кего stdin и stdout.
Для решения этой проблемы я подумал использовать файл FIFO, созданный командой mkfifo (мы находимся в Unix, особенно для пользователей Mac), и перенаправить программы stdin и stdout в этот файл:
my_program < fifofile > fifofile
Но я обнаружил некоторые трудности при чтении и записи в этот файл fifo.Поэтому я решил использовать 2 файла fifo, один для ввода и один для вывода.Итак:
exec my_program < fifofile_in > fifofile_out
(не знаю, почему я использую exec для перенаправления, но это работает ... и я в порядке с exec;))
Если я запускаю эту команду в оболочке, а в другой я пишу:
echo -n "date()" > fifofile_in
Процесс эхо-запроса успешен, и если я выполняю:
cat fifofile_out
Я могу видеть вывод my_program.Хорошо!Но я не хочу иметь дело с оболочкой, вместо этого я хочу иметь дело с программой, написанной мной, как этот скрипт на python:
import os, time;
text="";
OUT=os.open("sample_out",os.O_RDONLY | os.O_NONBLOCK)
out=os.fdopen(OUT);
while(1):
#IN=open("sample_in",'w' );
IN=os.open("sample_in",os.O_WRONLY)
#OUT=os.fdopen(os.open("sample_out",os.O_RDONLY| os.O_NONBLOCK |os.O_APPEND));
#OUT=open("sample_out","r");
print "Write your mess:";
text=raw_input();
if (text=="exit"):
break;
os.write(IN,text);
os.close(IN);
#os.fsync(IN);
time.sleep(0.05);
try:
while True:
#c=os.read(OUT,1);
c=out.readline();
print "Read: ", c#, " -- ", ord(c);
if not c:
print "End of file";
quit();
#break;
except OSError as e:
continue;
#print "OSError"
except IOError as e:
continue;
#print "IOError"
Где:
sample_in, sample_out
соответственноФайлы fifo, используемые для перенаправления в stdin и stdout (поэтому я пишу в stdin, чтобы передать входные данные my_program, и читаю из stdout, чтобы получить вывод my_program)
out
- мой дескриптор файла os.fdopenиспользуется для получения строк с out.readline()
вместо использования OUT.read(1)
(char by char)
time.sleep(0.05)
- для задержки на некоторое время, прежде чем перейти к чтению вывода my_program (необходимо для вычислений, иначе мне нечего читать).
Благодаря этому скрипту и my_program, работающим в фоновом режиме из оболочки, я могу писать в stdin и правильно читать из stdout, но путь к достижению этого кода был непростым: после прочтения всех постово fifo и чтении / записи из / в fifo файлов, я пришел с этим решением закрытия IN fd перед чтением из OUT, даже если файлы fifo отличаются!Из того, что я читал в Интернете и в статьях Stackoverflow, я подумал, что эта процедура предназначена для обработки только одного файла fifo, но здесь я имею дело с двумя (разными!).Я думаю, что это связано с тем, как я пишу в sample_in: я попытался выполнить сброс, чтобы выглядеть как echo -n
команда, но она кажется бесполезной.
Поэтому я хотел бы спросить вас, нормально ли это поведение, икак можно добиться того же с echo -n "...." > sample_in
и с другой оболочкой cat sample_out
?В частности, cat выводит данные непрерывно, как только я повторяю ввод в sample_in, но мой способ чтения - с блоками данных.
Большое спасибо, я надеюсь, что все достаточно ясно!