Tilde(〜)在subprocess.Popen()中不起作用

时间:2016-11-17 18:51:25

标签: python subprocess popen dd

当我在Ubuntu终端中运行时:

sudo dd if=/dev/sda of=~/file bs=8k count=200k; rm -f ~/file

它工作正常。

如果我通过Pythons subprocess.Popen()运行它:

output, err = subprocess.Popen(['sudo', 'dd', 'if=/dev/' + disk, 'of=~/disk_benchmark_file', 'bs=8k', 'count=200k'], stderr=subprocess.PIPE).communicate()
print err

它不起作用。我得到的错误是:

  

dd:无法打开'〜/ disk_benchmark_file':没有这样的文件或目录

如果我更改了Popen(),请将代字号~更改为/home/user,然后就可以了!

为什么会那样? 对我来说更重要的是:我怎样才能让它发挥作用?  我不知道生产中的用户名是什么。

3 个答案:

答案 0 :(得分:6)

您需要使用os.path.expanduser()包装这些路径名:

>>> import os
>>> os.path.expanduser('~/disk_benchmark_file')
'/home/dan/disk_benchmark_file'

在您的代码中出现:

['sudo', 'dd', 'if=/dev/' + disk, 'of=~/disk_benchmark_file', 'bs=8k', 'count=200k']

应替换为:

['sudo', 'dd', 'if=/dev/' + disk, 'of=' + os.path.expanduser('~/disk_benchmark_file'), 'bs=8k', 'count=200k']

答案 1 :(得分:4)

~是home的shell中的快捷方式。为了让你的命令被shell解释,你需要在你的Popen中设置shell=True

shell参数(默认为False)指定是否将shell用作要执行的程序。如果shell为True,建议将args作为字符串而不是序列

传递

https://docs.python.org/2/library/subprocess.html

请注意,虽然这样做有一些警告。

答案 2 :(得分:4)

import os
import shlex

outfile = os.path.expanduser('~/file')
cmd_string = 'sudo dd if=/dev/sda of=%s bs=8k count=200k; rm -f %s' % (outfile, outfile)
cmd_list = shlex.split(cmd_string)

# Then use cmd_list as argument for Popen

shlex.split是生成必须在子进程中用作command的列表的标准且最安全的方法。它能够处理所有异常并使您的代码更易于阅读

您可以使用home找到os.path.expanduser('~')