在python中重现'du'命令结果

时间:2015-04-07 20:41:35

标签: python

我正在尝试使用python重现du命令。问题是,有时我无法访问某些文件/目录,我通常可以通过使用Permission denied

重定向到null或隐藏grep -v行来跳过这些文件/目录

这是函数

def du(path):
    """disk usage in kilobytes"""
    print "calculating disk usage for " + path + " ..."
    # return subprocess.check_output(['du', '-s',
    # path]).split()[0].decode('utf-8')
    try:
        output = subprocess.check_output(['ls', '-d', path, '|', 'parallel', '--no-notice', 'du', '-s', '2>&1', '|', 'grep', '-v', '"Permission denied"'], shell=True, stderr=subprocess.STDOUT).split()[0].decode('utf-8')
    except subprocess.CalledProcessError as e:
        raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
    return output

问题是它捕获了退出代码并且无论如何都会抛出错误,是否有什么我可以在此函数中更改以跳过权限被拒绝的行?

由于

修改

我添加了对我有用的功能的修改,以防有人想在某一天完成这项工作是更新的功能

def du(path):
    """disk usage in kilobytes"""
    print "calculating disk usage for " + path + " ..."
    # return subprocess.check_output(['du', '-s',
    # path]).split()[0].decode('utf-8')
    try:
        p1 = subprocess.Popen(('ls', '-d', path), stdout=subprocess.PIPE)
        p2 = subprocess.Popen(('parallel', '--no-notice', 'du', '-s', '2>&1'), stdin=p1.stdout, stdout=subprocess.PIPE)
        p3 = subprocess.Popen(('grep', '-v', '"Permission denied"'), stdin=p2.stdout, stdout=subprocess.PIPE )
        output = p3.communicate()[0]
        #output = subprocess.check_output(['ls', '-d', path, '|', 'parallel', '--no-notice','du', '-s', '2>&1', '|', 'grep', '-v', '"Permission denied"'], shell=True, stderr=subprocess.STDOUT).split()[0].decode('utf-8')
    except subprocess.CalledProcessError as e:
        raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
    return ''.join([' '.join(hit.split('\t')) for hit in output.split('\n') if len(hit) > 0 and not "Permission" in hit])

2 个答案:

答案 0 :(得分:0)

如果您不希望它抛出错误,请不要在您的except块中使用raise。也许只是打印到stderr。您可能还希望更完整并检查特定错误,以确保您只是避免抛出特定错误。

另外,您可能需要考虑使用os.path.getsize而不是使用shell来解析ls。

答案 1 :(得分:0)

也许您可以查看du模块的内置sh

from sh import du

然后您可以使用您想要的参数调用它:

du()

您可以在此处找到模块上所需的一切:https://github.com/amoffat/sh(包括安装,并包括对sudo的讨论)。

答曰:

  

sh(以前的pbs)是一个完整的子进程替换   Python 2.6 - 3.4,允许您调用任何程序,就像它是一样   功能...