如何让终端中运行的Python脚本从另一Shell实例读取标准输入?
解决方法:使用命名管道(mkfifo)传递输入
直接写入/proc/PID/fd/0无效的原因是,该文件描述符指向伪终端(PTY)的主设备,直接写入的内容只会在终端界面显示,并不会被程序的标准输入流读取——程序的stdin监听的是PTY的从设备,需要通过终端驱动的正常流程传递输入,而非直接写入主设备的fd。
用命名管道(FIFO)可以解决这个问题,以下是两种可行的实现方式:
方式一:启动Python时关联FIFO(同时保留终端输入)
这种方法让Python程序同时监听终端输入和FIFO输入,既支持手动在终端输入,也能从其他bash脚本通过FIFO传数据。
- 创建命名管道
在终端执行:
mkfifo python_input_fifo
- 修改Python脚本
使用select监听多个输入流(终端stdin和FIFO):
import sys import select def process_input(input_data): # 处理输入的逻辑 print(f"Processed input: {input_data}") return 1 # 用于递增计数器 if __name__ == "__main__": input_count = 0 # 以只读非阻塞模式打开FIFO fifo = open("python_input_fifo", "r") # 监听的输入流集合 inputs = [sys.stdin, fifo] while True: try: # 等待可读的输入流 readable, _, _ = select.select(inputs, [], []) for stream in readable: if stream == sys.stdin: input_data = sys.stdin.readline().strip() else: input_data = fifo.readline().strip() if not input_data: continue # 忽略空输入 if input_data == "exit": fifo.close() sys.exit(0) input_count += process_input(input_data) print(f"Input count: {input_count}") except (KeyboardInterrupt, EOFError): fifo.close() break
- 启动Python程序
直接在终端运行修改后的脚本:
python3 your_script.py
- 从其他bash脚本传递输入
在另一个终端或bash脚本中,向FIFO写入内容:
echo "some text" > python_input_fifo # 传递exit命令让程序退出 echo "exit" > python_input_fifo
方式二:不修改Python脚本,启动时重定向stdin到FIFO
如果不想修改Python脚本,可以在启动时将程序的stdin重定向到FIFO,但这样程序无法接收终端的手动输入,适合仅需从脚本传递输入的场景。
- 创建命名管道
mkfifo python_input_fifo
- 启动Python程序并重定向stdin
python3 your_script.py < python_input_fifo
- 从其他bash脚本传递输入
在另一个终端或脚本中写入FIFO:
echo "some text" > python_input_fifo echo "exit" > python_input_fifo
注意事项
- 命名管道是临时文件,使用完可通过
rm python_input_fifo删除。 - 方式一中,FIFO被关闭后程序仍会监听终端输入,直到手动输入
exit或按Ctrl+C退出。 - 写入FIFO时,只有当有程序读取它时,写入操作才会完成,否则会阻塞(可通过非阻塞模式避免)。
内容的提问来源于stack exchange,提问作者teoML
相关产品推荐
相关产品推荐

