Python中向Popen stdin输入带回车的fdisk命令遇问题,求等效实现
解决subprocess执行fdisk交互命令的问题
你的问题根源在于:你把管道符|和后续的sudo fdisk命令都当成了echo的参数,而subprocess默认不会自动解析shell的管道语法——当你用列表形式传递命令参数时,每个元素都会被当成前一个命令的参数,所以实际执行的只是echo把后面的一串字符串打印出来,根本没触发fdisk的执行。
下面给你两种正确的实现方式,推荐用第一种(更安全):
方式一:直接通过stdin传递交互命令(推荐)
这种方式不需要依赖shell解析,避免了shell注入的风险,而且能精准控制输入到fdisk的内容:
import subprocess # 构造fdisk需要的交互命令,转成字节流(注意每个命令后加换行符) fdisk_input = b"o\nn\np\n1\n\n\nw\n" # 启动sudo fdisk进程,指定stdin、stdout、stderr为管道 proc = subprocess.Popen( ["sudo", "fdisk", "/dev/xvdm"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) # 将交互命令传入stdin,同时获取输出 stdout, stderr = proc.communicate(input=fdisk_input) # 打印结果(根据需要处理解码) print("标准输出:", stdout.decode("utf-8")) print("错误输出:", stderr.decode("utf-8"))
这个逻辑是直接启动sudo fdisk进程,然后把我们需要的交互步骤(创建新分区表、新建主分区、保存退出)通过communicate()的input参数传递给它的stdin,完全模拟手动输入的过程。
方式二:使用shell=True解析完整命令(不推荐)
如果你一定要用管道的方式,可以把整个命令作为字符串传递,并设置shell=True,让shell来解析管道语法,但这种方式存在shell注入风险,尤其是当命令中包含变量时要格外小心:
import subprocess # 把完整命令作为字符串传入 full_command = "echo -e 'o\nn\np\n1\n\n\nw' | sudo fdisk /dev/xvdm" proc = subprocess.Popen( full_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, stderr = proc.communicate() print("标准输出:", stdout.decode("utf-8")) print("错误输出:", stderr.decode("utf-8"))
注意事项
- 执行fdisk需要sudo权限,确保你的脚本运行时拥有足够的权限(比如用sudo运行脚本)
- 操作磁盘风险很高,一定要确认目标设备
/dev/xvdm是你要操作的磁盘,避免误删数据
内容的提问来源于stack exchange,提问作者M Leonard




