如何在Python中启动带用户输入的Perl脚本并作为函数使用
Python调用带STDIN交互的Perl脚本实现方案
之前调用失败的核心原因
默认使用subprocess.run/Popen启动子进程时,不会自动将当前Python进程绑定的终端标准流透传给Perl子进程:Perl脚本执行<STDIN>读取用户输入时,拿不到终端输入流,会直接读到EOF终止读取,因此只会打印提示文字、不会等待用户输入就直接退出。
方案1:保留原生终端交互(和直接跑Perl脚本体验完全一致)
这种方式不需要做额外的流转发,直接让Perl脚本继承当前Python进程的终端输入输出,交互逻辑和你手动在命令行跑Perl脚本没有区别,可以直接当做普通Python函数调用。
首先确认你的Perl脚本(示例保存为check_hear.pl)内容如下:
use strict; use warnings; # 开启标准输出即时刷新,避免提示卡在缓冲区不显示 $| = 1; print "\nCan you hear me ? (1/0) "; my $choice = <STDIN>; if ($choice == 1){ print "\nYES"; }
Python端调用代码:
import subprocess def call_perl_interact(script_path: str) -> int: # 三个标准流全部设为None,即继承当前父进程的终端流 ret = subprocess.run( args=["perl", script_path], stdin=None, stdout=None, stderr=None, text=True ) return ret.returncode # 像普通Python函数一样调用即可 if __name__ == "__main__": exit_code = call_perl_interact("check_hear.pl") print(f"\n脚本执行结束,退出码:{exit_code}")
方案2:Python端自动控制输入输出(无终端交互场景用)
如果你不需要用户手动在终端输入,而是要在Python代码里预设输入、捕获脚本输出,可以用管道方式实现:
import subprocess def call_perl_auto_input(script_path: str, input_content: str) -> dict: proc = subprocess.Popen( args=["perl", script_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) # 注意输入末尾要加换行符,Perl的<STDIN>读到换行才会完成读取 stdout, stderr = proc.communicate(input=f"{input_content}\n", timeout=10) return { "exit_code": proc.returncode, "stdout": stdout, "stderr": stderr } # 调用示例:自动传入参数1 if __name__ == "__main__": result = call_perl_auto_input("check_hear.pl", "1") print(f"脚本输出内容:{result['stdout']}") # 输出包含提示语和YES
注意事项
- 用管道模式时不要手动循环读写
stdin/stdout,容易因为管道缓冲区占满触发死锁,优先用communicate()方法处理输入输出 - 传给Perl的输入末尾必须加换行符,否则
<STDIN>会一直等待输入结束,表现为进程卡住 - 如果Perl脚本输出不显示,在Perl脚本开头加
$| = 1;关闭标准输出缓冲即可
内容的提问来源于stack exchange,提问作者Martin von polier
相关产品推荐
相关产品推荐

