我正在尝试通过发送一系列命令并捕获输出来测试特定的聊天程序。
我如何通过:
sleep 2
echo test
sleep 2
echo test1
Run Code Online (Sandbox Code Playgroud)
我已经试过了:
(sleep 2; echo test; sleep 2; echo test1) | python3 test.py
Run Code Online (Sandbox Code Playgroud)
但它只打印第一部分,而第二部分我什么也没得到。相反,它进入了一个无限循环。
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()
Run Code Online (Sandbox Code Playgroud)
我应该提到这不是完整的程序,但是它是帮助重新创建完全相同的效果的部分。
你的例子进入循环,因为在echo test1 标准输入关闭后read()总是返回空。此外,您不应该使用另一个阻塞调用select。如果您要在多个对象上使用它,您仍然可能被readline
前一个事件阻止。
要从stdin 中读取一行,您不需要使用
select.select(). 可能是实现这一目标的最简单方法:
for line in sys.stdin:
print(line)
Run Code Online (Sandbox Code Playgroud)
如果您想使用其中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)
Run Code Online (Sandbox Code Playgroud)
当一个对象准备好时,
select.select
解除阻塞。在这种情况下,唯一的对象是stdin。对于多个对象,您需要检查其返回值select.select以找出哪个对象已准备就绪。os.read()用于从stdin进行非阻塞读取
(或者:可以stdin.read(1)一次读取一个字符)。
read.split("\n")用于查找换行符,请注意,单次读取可能会产生不止一行。
| 归档时间: |
|
| 查看次数: |
9076 次 |
| 最近记录: |