Python 使用subprocess.check_输出检查带有2>/dev/null

Python 使用subprocess.check_输出检查带有2>/dev/null,python,macos,subprocess,Python,Macos,Subprocess,我使用的是Mac OS X Yosemite 10.10和Python 2.7 如果我在命令行中键入以下命令:du-g-d1/Users 2>/dev/null,那么一切都可以正常工作 现在,我的目标是在python脚本中使用该命令 我的想法是使用以下方法: import subprocess output = subprocess.check_output(['du', '-g', '-d1', '/Users', '/dev/null']) 但我得到了这个错误: Traceback (m

我使用的是Mac OS X Yosemite 10.10和Python 2.7

如果我在命令行中键入以下命令:
du-g-d1/Users 2>/dev/null
,那么一切都可以正常工作

现在,我的目标是在python脚本中使用该命令

我的想法是使用以下方法:

import subprocess

output = subprocess.check_output(['du', '-g', '-d1', '/Users', '/dev/null'])
但我得到了这个错误:

Traceback (most recent call last):
  File "./verifications.py", line 1, in <module>
    output = subprocess.check_output(['du', '-g', '-d1', '/Users', '/dev/null'])
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 537, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['du', '-g', '-d1', '/Users', '/dev/null']' returned non-zero exit status 1
回溯(最近一次呼叫最后一次):
文件“/verifications.py”,第1行,在
output=子流程。检查_输出(['du','-g','-d1','/Users','/dev/null'])
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”,第537行,在check_输出中
引发被调用的进程错误(retcode,cmd,output=output)
subprocess.CalledProcessError:命令'['du','-g','-d1','/Users','/dev/null']'返回非零退出状态1

此外,当我在local everything中运行
子进程。检查_输出(['du'、'-g'、'-d1'、'/Users'、'/dev/null'])
时,当我使用Apple的共享屏幕工具登录共享iMac时,会发生错误。我感觉问题可能是由于权限问题,但我找不到任何东西。

对于
2>/dev/null
,使用
子进程.Popen
调用系列控制文件描述符2重定向的适当方法是
stderr=

# Python 2.x, or 3.0-3.2
output = subprocess.check_output(['du', '-g', '-d1', '/Users'],
                                 stderr=open('/dev/null', 'w'))
…或者,如果Python支持
subprocess.DEVNULL

# Python 3.3 or newer
output = subprocess.check_output(['du', '-g', '-d1', '/Users'], stderr=subprocess.DEVNULL)

顺便说一句,就我个人而言,我建议更像这样:

p = subprocess.Popen(['du', '-g', '-d1', '/Users'],
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
  raise Exception(stderr)

…它不是将
stderr
发送到
/dev/null
,而是在命令失败时将其保留以生成有用的异常。(显然,选择Exception的适当子类)。

/dev/null
是重定向,而不是参数。也就是说,它告诉shell如何在运行命令之前为命令设置文件描述符,并且实际上根本没有传递给
du
命令……哦——在您的问题的前面,您使用了
2>/dev/null
。这意味着不同的东西。请尽量保持一致。但这仍然是使用它的方式。该文档正在传递一个文本参数,而不是执行重定向。也就是说,它运行的是
ls-l/dev/null
,而不是
ls-l>/dev/null
ls-l2>/dev/null
。这三个命令是完全不同的。哦,所以我想我有点混淆了。不确定我是否理解正确,但我现在得到的是:>>>导入子进程>>>输出=子进程。检查输出(['du','-g','-d1','/Users',],stdout=open('/dev/null','w')回溯(最近的调用最后一次):文件“”,第1行,在文件中“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”,第529行,在check_output raise ValueError('stdout参数不允许,它将被重写。')ValueError:stdout参数不允许,它将被重写。重新读取答案(如果浏览器没有跟上编辑,则重新加载)。您会注意到,我使用的是
stderr=
,而不是
stdout=
。stdout是fd1——它是
/dev/null
重定向的内容,正如我在完全删除该部分之前所说的,重定向对于
check\u output()
。假设我们忘记了我的想法。在python脚本中如何执行du-g-d1/Users 2>/dev/null?/edit我需要捕获结果,以便稍后在脚本中使用。就个人而言,我会收集stdout和stderr——扔掉错误消息,而不是记录它们以用于异常是愚蠢的。这样做,可以使用
communicate()
呼叫。如果你想要一个准确的
/Users
及其所有子目录的总大小,你需要+rx到它的所有子目录。这是绕不开的。如果你拥有的
+rx
权限都是
/Users
,你只能得到/Users本身的文件大小,这不是很有帮助。无论如何,这现在是完全关闭的opic;关于您需要使用
du
的权限的问题应单独询问(可能是在或上)。如果您想忽略错误并接受不准确的结果,请执行明显的操作并删除
引发异常