从命名管道获取标准输入


10

我想做的是在终端窗口中运行python,并从命名管道重定向它的stdin。然后,我在另一个终端中写入命名管道,并在python上执行该命令。

1号航站楼:

mkfifo p1
python < p1

2号航站楼:

echo -n "print \"Hello World\"" > p1

发生的是-python打印Hello World并退出。我想做的是保持python运行以接受下一条命令。如何在外壳中执行此操作?

Answers:


10

你需要

  • 交互式运行python,即使其stdin不是终端:使用 python -i
  • 保持管道的写入端处于打开状态,否则python将检测到EOF并退出。

所以:

python -i < p1

在其他地方:

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

谢谢!有效。我对您所做的不熟悉。您能否在答案中添加一些详细信息,以解释发生了什么情况。在exec 3> p1做什么,什么是&3exec 3> &1?谢谢。
卢勋爵。

1
您的回答让我想起了这面旗帜-sphotos-b.xx.fbcdn.net/hphotos-ash4 / ...,这是一个朋友在facebook上的封面照片:-)
勋爵。

一个问题,exec 3>&-exec 3>&1这里的一样吗?
通配符

1
@Wildcard我怀疑我打算在3>&-这里写。3>&1也会工作,但毫无意义。谢谢
斯特凡Chazelas

5

您可以用来tail -fecho写入后将fifo保持打开状态。

tail -n1 -f p1 | python

为什么这样做

python正在从阅读p1。当到达文件末尾时,它将停止读取。即使文件是命名管道,这也是文件读取的正常行为。tail带有-f(follow)标志的文件将在到达文件末尾后继续读取文件。


echo "print \"Hello World\" " > p1在第二个终端中尝试过,但没有任何反应-但终端也未受阻。带有python的终端保持阻塞,直到^c退出并退出并终止python,并显示python的键盘中断消息。
卢勋爵。

tail -f通过命名管道解压缩块分割的tar归档文件时,我使用了此技巧。效果很好。
Mael

2

您需要一次发送整个程序。

当您调用run时python < p1,shell会在调用python之前等待输入。也就是说,蟒蛇甚至没有开始执行所有,直到整个数据流已经被shell读取,然后在其完整地传递python

即使运行它python -u p1(即,未缓冲并从file读取p1),它python也会尝试在执行任何文件之前先读取整个文件。

试试这个实验。

1号航站楼:

mkfifo p1
python < p1

2号航站楼:

cat > p1
print "Hello World"
print "Hello World"

您会看到您可以发送多行,但是术语1中的python什么都不做。现在按ctrl+ D。整个程序立即执行。

因此,总而言之,如果您希望python从管道读取数据,则需要发送整个程序。您不能以这种方式交互使用python。


1

也许尾部方法更好(更灵活),但可以选择:

{ echo -n "print \"Hello World\""; cat; } > p1

这不符合我的要求。-n可能已被删除。而在这之后,0与终端echo命令被阻塞,直到我按1 Python不执行命令^cecho终端和进程都终止。
卢勋爵。

1
@LordLoh。可能是一个缓冲问题。如果已创建足够的输出,则python可能会执行该命令,以便第一行最终被写入FIFO。但是,由于存在可行的解决方案,因此花精力解决这个问题没有任何意义。
Hauke Laging
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.