在 Python 中一次读取 stdin 行

2023-12-30

我试图通过发送一系列命令并捕获输出来测试特定的聊天程序。

我怎样才能通过:

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()

我应该提到,这不是完整的程序,但它是帮助重新创建完全相同效果的部分。


你的例子会循环,因为之后echo test1 stdin已关闭并且read()总是返回空。 另外你不应该使用另一个阻塞调用select。如果你愿意 在多个对象上使用它,您仍然可能被阻止readline从上一个事件。

用于一次读取一行stdin你不需要使用select.select()。可能是实现这一目标的最简单方法:

for line in sys.stdin:
    print(line)

如果你想使用stdin或作为参数的文件列表 你的程序,Python的fileinput https://docs.python.org/3/library/fileinput.html模块 是开箱即用的解决方案。

如果您想要/需要使用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 https://docs.python.org/3/library/select.html#select.select解锁。本例中唯一的对象是stdin。与不止一个 您需要检查的返回值的对象select.select找出来 哪一个已经准备好了。os.read()用于进行非阻塞读取stdin(或者: 可以使用stdin.read(1)一次读取一个字符)。read.split("\n")用于查找换行符,请注意它是 一次读取可能会产生不止一行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Python 中一次读取 stdin 行 的相关文章

随机推荐