我遇到了一个问题:我有一个程序在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就会连续输出数据,但我的阅读方式是使用数据块。
非常感谢,我希望一切都很清楚!