Python脚本无输入时卡在sys.stdin.readlines()的解决咨询
解决Python脚本无输入时卡在sys.stdin.readlines()的问题
这个问题的核心是sys.stdin.readlines()是阻塞调用——当标准输入没有数据时,它会一直等待用户输入,根本不会走到你判断lines是否为空的步骤。要解决这个问题,你需要在调用readlines()之前先判断:标准输入到底有没有数据可读?
下面提供两种实用的解决方案,适配不同场景:
方案一:用select模块检查输入是否可读
select模块可以帮你在不阻塞的情况下检查文件描述符是否有数据,非常适合通用场景(不管是终端输入还是管道/重定向输入都能处理)。
import sys import select def process_input(): args = sys.argv[1:] # 处理文件输入的逻辑 if len(args) != 0 and args[0] != '-': input_file = args[0] try: with open(input_file, 'r') as f: lines = f.readlines() # 这里添加你处理lines的逻辑 return lines except Exception as e: print(f"读取文件出错: {e}") return [] else: # 检查stdin是否有数据可读,超时设为0表示立即返回 readable, _, _ = select.select([sys.stdin], [], [], 0) if readable: # 有输入,读取所有行 lines = sys.stdin.readlines() # 添加处理逻辑 return lines else: # 无输入,直接退出函数 print("未提供任何输入,退出当前函数") return []
原理说明
select.select会同时监听一组文件描述符的可读、可写、异常状态。我们只关心sys.stdin的可读状态,设置超时为0后,函数会立即返回结果:
- 如果
readable列表包含sys.stdin,说明有数据可以读取; - 如果为空,说明没有输入,直接退出即可。
方案二:判断是否为终端输入
如果你的脚本主要在终端环境使用,可以通过os.isatty()判断stdin是否连接到终端——如果是终端且没有输入,直接退出;如果是管道/重定向输入,则正常读取。
import sys import os def process_input(): args = sys.argv[1:] # 处理文件输入的逻辑 if len(args) != 0 and args[0] != '-': input_file = args[0] try: with open(input_file, 'r') as f: lines = f.readlines() # 添加处理逻辑 return lines except Exception as e: print(f"读取文件出错: {e}") return [] else: # 判断stdin是否连接到终端 if os.isatty(sys.stdin.fileno()): # 终端环境下无输入,直接退出 print("终端未提供输入,退出当前函数") return [] else: # 非终端(管道/重定向),读取输入 lines = sys.stdin.readlines() # 添加处理逻辑 return lines
原理说明
os.isatty()会检查文件描述符是否对应一个终端设备:
- 当你直接在终端运行脚本且没有输入时,
sys.stdin是终端设备,此时直接退出; - 当通过管道(比如
echo "test" | python your_script.py)或文件重定向(python your_script.py < input.txt)输入时,sys.stdin不是终端,正常读取即可。
总结
- 永远不要在不确定有输入的情况下直接调用
sys.stdin.readlines(),它会阻塞程序; - 通用场景优先选
select方案,终端专属场景可以用os.isatty方案; - 记得在处理文件输入时用
with语句自动关闭文件,避免资源泄漏。
内容的提问来源于stack exchange,提问作者SaiRam
相关产品推荐
相关产品推荐

