【问题标题】:using python subprocess to a get directory size on mac instead of os.walk使用 python 子进程在 mac 上获取目录大小而不是 os.walk
【发布时间】:2013-11-03 01:22:45
【问题描述】:

我对 python 和 subprocess 模块比较陌生。

我正在尝试使用 mac osx 上的子进程通过 python 获取目录大小。 os.walk 需要很长时间来处理大型目录。我希望让子进程使用 shell 命令执行此操作并加快结果。这个 shell 命令对我有用,但我不能让它从子进程中工作?

( cd /test_folder_path && ls -nR | grep -v '^d' | awk '{total += $5} END {print total}' )

这就是我尝试在 python 中创建子进程的方式。

import shlex 
import subprocess

target_folder = "/test_folder_path"
command_line = "( cd " + target_folder + " && ls -nR | grep -v '^d' | awk '{total += $5} END {print total}' )"
args = shlex.split(command_line)
print args
folder_size = subprocess.check_output(args)
print str(folder_size)

在 python 中调用 subprocess.check_ouput 时出现以下错误

folder_size = subprocess.check_output(args) 文件“/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”,第 568 行,在 check_output 进程 = Popen(stdout=PIPE, *popenargs, **kwargs) init 中的文件“/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”,第 711 行 读错,写错) _execute_child 中的文件“/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”,第 1308 行 引发 child_exception OSError: [Errno 2] 没有这样的文件或目录

当我在 shell 命令中使用相同的目录时,它可以工作并为我提供正确的目录大小。

任何帮助使这种方法发挥作用或向我指出更好的方法将不胜感激。

【问题讨论】:

  • 怎么了?蟒蛇错误? Cmd 行语法错误?答案错误?
  • 试试cd /test_folder_path && du -c | tail -n 1

标签: python macos shell directory subprocess


【解决方案1】:

python 的子进程默认使用shell=False。为了使用管道运行子命令,您需要 shell 以防止 python 将管道(和 &&)解释为 cd 的参数。

target_folder = "/test_folder_path"
command_line = "cd " + target_folder + " && ls -nR | grep -v '^d' | awk '{total += $5} END {print total}'"
folder_size = subprocess.check_output(command_line, shell=True)

我已经尝试了上述方法,只使用了drawk建议的命令:

>>> import subprocess
>>> folder_size = subprocess.check_output('cd ~/mydir && du -c | tail -n 1', shell=True)
>>> folder_size
b'113576\ttotal\n'

一切似乎都很好。

如 cmets 中所述,subprocess.Popen(以及扩展名为 check_output)还接受 cwd 参数,该参数是运行命令的目录。这消除了在命令中更改目录的需要:

>>> import subprocess
>>> result = subprocess.check_output('du -c | tail -n 1', cwd='/path/to/home/mydir', shell=True)
>>> result
'113576\ttotal\n'

【讨论】:

  • 很好的答案,但可以通过跳过 "cd " + target_folder + " && " 来进一步完善,转而使用 'cwd' 参数来检查输出。
  • @tdelaney -- 太棒了。我以前从未需要使用该关键字。太棒了。
  • 谢谢!!这正是我正在寻找的。谢谢大家的帮助
  • @drewk -- 当然,在这一点上,多亏了 tdelaney 的好建议,我们最好还是移除到tail 的管道,然后从 python 读取输出流(保持最后一行)。然后我们可以再次消除外壳。
  • @mgilson: we would probably be better off removing the pipe to tail and just reading the output stream from python (keeping the last line) 更好。我主要是对试图用grep 解析ls 的OP 做出反应。由于 UNIX 允许在文件名中包含几乎任何字符,包括空格和换行符,解析 ls 是有问题的......谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 2021-06-13
  • 1970-01-01
  • 2017-05-30
相关资源
最近更新 更多