波浪号 (~) 在 subprocess.Popen() 中不起作用

Tilde (~) isn't working in subprocess.Popen()

当我 运行 在我的 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: failed to open '~/disk_benchmark_file': No such file or directory

如果我将 Popen() 中的波浪号 ~ 更改为 /home/user,那么它就可以工作了!

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

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

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

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

注意,虽然有一些关于这样做的警告。

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 的列表的标准且最安全的方法。它能够处理所有异常并使您的代码更易于阅读

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

您需要用 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']