Unix:为什么我需要关闭输入FIFO到我的程序才能从输出FIFO

时间:2018-04-25 13:01:10

标签: python unix io-redirection mkfifo

我遇到了一个问题:我有一个程序在shell中运行,根据用户输入进行一些计算,我可以以交互方式启动这个程序,这样它就会继续询问输入并输出它用户按Enter键后的计算。所以它在shell中保持打开状态,直到用户输入退出单词。

我想要做的是以这样的方式创建一个接口,即用户必须在shell外的其他位置输入输入并使用pipe,fifo等,输入被带到该程序,其输出转到这个界面。

简而言之:我有一个漫长的运行过程,我需要在需要时附加我的stdin和stdout接口。

对于这类问题,我想使用mkfifo命令生成的FIFO文件(我们在Unix中,尤其是Mac用户),并将程序stdin和stdout重定向到这个文件:

my_program < fifofile > fifofile

但是我发现在读取和写入这个fifo文件时遇到了一些困难。所以我决定使用2个fifo文件,一个用于输入,一个用于输出。所以:

exec my_program < fifofile_in > fifofile_out

(不知道为什么我使用exec进行重定向,但是它有效...而且我对exec没问题;)

如果我在shell中启动此命令,在另一个中我写道:

echo -n "date()" > fifofile_in

回声过程是成功的,如果我这样做:

cat fifofile_out

我能看到my_program输出。好!但是我不想处理shell,而是想处理我编写的程序,比如这个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分别是用于重定向到stdin和stdout的fifo文件(因此我写入stdin以便为my_program提供输入,我从stdout读取以获取my_program输出)

out是我的os.fdopen文件描述符,用于获取out.readline()的行,而不是使用OUT.read(1)(char by char)

time.sleep(0.05)在读取my_program输出之前有一段时间的延迟(需要进行计算,否则我没有阅读)。

使用shell在后台运行此脚本和my_program,我能够正确写入stdin并从stdout读取,但实现此代码的过程并不容易:阅读完所有帖子之后关于fifo和从/到fifo文件的读/写,我提出了这个解决方案,在从OUT读取之前关闭IN fd,即使fifo文件不同!从我在互联网和Stackoverflow文章中读到的内容,我认为这个程序仅用于处理一个fifo文件,但在这里我处理两个(不同的!)。我认为这与我如何写入sample_in有关:我试图刷新看起来像echo -n命令,但它似乎没用。

所以我想问你这种行为是否正常,如何用echo -n "...." > sample_in和其他shell cat sample_out实现同样的目的?特别是,只要我在sample_in中回显输入,cat就会连续输出数据,但我的阅读方式是使用数据块。

非常感谢,我希望一切都很清楚!

0 个答案:

没有答案