Unix: почему мне нужно закрыть входной FIFO для моей программы, прежде чем я смогу читать с его выходного FIFO - PullRequest
0 голосов
/ 25 апреля 2018

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

Что я хочу сделать, это создать интерфейс таким образом, чтобы пользователь мог вводить ввод в другом месте вне оболочки и использовать 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, но мой способ чтения - с блоками данных.

Большое спасибо, я надеюсь, что все достаточно ясно!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...