如何在Python子进程模块中使用管道命令串?

1 投票
3 回答
1665 浏览
提问于 2025-04-16 18:08

我想用一个Python脚本在Ubuntu上对一个新的空硬盘进行分区。

如果用bash脚本或者在命令行中,可以这样做:

$echo -e "n\np\n1\n\n\nw\n" | sudo fdisk /dev/X

这里的X就是你要操作的硬盘。

我尝试把这个过程转成Python脚本,使用了subprocess模块,代码如下:

p = subprocess.Popen(cmdString, stdout=subprocess.PIPE, \
                     close_fds=False, stderr=subprocess.PIPE,shell=True)
stdoutAndErr = p.communicate()

这里的cmdString就是上面提到的"echo -e ..."字符串。

不过这样并不奏效。输出的结果只是fdisk打印出了一些命令选项,显然我发送的内容不被它接受。

那么,上面这种简单的方法到底哪里出了问题呢?

3 个回答

0

你实际上需要使用两个管道,第一个管道的输出会作为第二个管道的输入,所以你可以这样做:

 p=subprocess.Popen(['printf','n\np\n1\n\n\nw\n'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 p1=subprocess.Popen(['fdisk','/dev/X'],stdin=p.stdout, stderr=subprocess.PIPE, stdout= subprocess.PIPE).wait()

额外提示:注意到wait()这个部分,这样你的脚本会等到fdisk完成后再继续执行。

0

你不能把一个复杂的命令字符串直接传给Popen()函数。这个函数的第一个参数需要的是一个列表。shlex模块,特别是它的split()函数,会对你很有帮助。此外,subprocess的文档里也有一些使用它的例子。

所以你需要做的类似于:

import shlex, subprocess
command_line = 'echo -e "n\np\n1\n\n\nw\n" | sudo fdisk /dev/X'
args = shlex.split(command_line)
p = subprocess.Popen(args) # Success!
0

你可能需要的就是这个“自带电池”的 pipes 模块。Doug Hellman 写了一篇很不错的 文章,介绍了如何使用这个模块来实现你想要的功能。

撰写回答