我试图通过发送一系列命令并捕获输出来测试特定的聊天程序。
我如何通过:
sleep 2
echo test
sleep 2
echo test1
我试过这个:
(sleep 2; echo test; sleep 2; echo test1) | python3 test.py
但它只打印第一部分,而第二部分我什么都没得到。它反而进入了无限循环。
python程序的代码是:
import sys, select
while True:
socket_list = [sys.stdin]
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])
for sock in read_sockets:
message = sys.stdin.readline()
sys.stdout.write("> %s: ")
sys.stdout.flush()
我应该提到这不是完整的程序,但它是帮助重新创建完全相同效果的部分。
答案 0 :(得分:3)
您的示例进入循环,因为echo test1
stdin 关闭后read()
始终返回空。
此外,您不应该使用select
进行其他阻止通话。如果你能
在多个对象上使用它,您仍然可以被readline
阻止
来自上一次活动。
从 stdin 读取一行时,您不需要使用
select.select()
。可能是实现这一目标的最简单方法:
for line in sys.stdin:
print(line)
如果要使用stdin
或文件列表作为参数
你的程序,Python
fileinput
模块
是开箱即用的解决方案。
如果你想/需要使用select.select()
:
import os, sys, select
buffer = ""
while True:
select.select([sys.stdin.fileno()], [], [])
read = os.read(sys.stdin.fileno(), 512)
# empty read: EOF
if len(read) == 0:
# buffer might not be empty
if len(buffer) > 0:
sys.stdout.write(buffer + "\n")
break
# find newlines
parts = read.split("\n")
buffer += parts.pop(0)
while len(parts) > 0:
sys.stdout.write(buffer + "\n")
buffer = parts.pop(0)
物体准备好后,
select.select
疏导。在这种情况下唯一的对象是 stdin 。不止一个
对象,您需要检查select.select
的返回值以查找
哪一个准备好了。 os.read()
用于执行非阻塞读取
stdin (或者:
它可以使用stdin.read(1)
一次读取一个字符)。
read.split("\n")
用于查找换行符,请注意它
可能一次读取会产生多行。
答案 1 :(得分:1)
在strace
上运行cat
之后,我创建了这个:
import sys
while True:
data = sys.stdin.read()
if not len(data):
break
sys.stdout.write(data)
<强>命令强>
(sleep 2; echo test; sleep 2; echo test1) | python3 test.py
<强>输出强>
test
test1
这个解决方案依赖于这个事实:
如果已到达文件末尾,f.read()将返回一个空字符串('')。
如果您需要使用select
的版本:
import os
import select
import sys
while True:
rlist = [sys.stdin.fileno()]
wlist = []
xlist = []
rlist, wlist, xlist = select.select(rlist, wlist, xlist)
if sys.stdin.fileno() in rlist:
data = os.read(sys.stdin.fileno(), 4096)
if not len(data):
break
sys.stdout.write(data)