使用os.system断开管道获取文件夹大小

时间:2015-08-20 11:37:39

标签: python os.system broken-pipe

我有一个python脚本,我希望得到一个文件夹的大小(尽可能快),如下所示:

 os.system("du -k folder |sort -nr| head -n 1 > size")

虽然看起来有效,但我收到此错误

sort: write failed: standard output: Broken pipe
sort: write error

我该如何解决?

3 个答案:

答案 0 :(得分:1)

我可以通过在大目录上创建du来重现。之所以发生这种情况,是因为对于大型目录,排序过程会对其标准输入进行多次写入,head只要看到它有一行就会关闭其标准输入(并退出)。

你需要解决它吗?恕我直言这是命令headsort的工作方式,并不意味着你的价值不正确。所以我只是将标准错误重定向或排序到/dev/null以删除消息:

 os.system(" du -k folder |sort -nr 2>/dev/null| head -n 1")

但正如Padraic Cunningham已经说过的那样,我认为这个命令真的很复杂,只是为了找到一个目录的总大小。

答案 1 :(得分:1)

正如@mdurant在评论中所说:subprocess模块优先于os.system()。您可以在没有中间文件的情况下将外部程序的输出直接输入到程序中,并且在程序和外部程序之间也没有启动额外的shell进程。

IPython会话中的示例:

In [5]: subprocess.check_output(['du', '-sk', 'tmp'])
Out[5]: '101160\ttmp\n'

In [6]: subprocess.check_output(['du', '-sk', 'tmp']).split('\t', 1)
Out[6]: ['101160', 'tmp\n']

In [7]: subprocess.check_output(['du', '-sk', 'tmp']).split('\t', 1)[0]
Out[7]: '101160'

In [8]: int(subprocess.check_output(['du', '-sk', 'tmp']).split('\t', 1)[0])
Out[8]: 101160

答案 2 :(得分:0)

Python设置SIGPIPE信号在启动时被忽略。因此,sorthead已经完成时尝试写入管道并关闭其标准输入,EPIPE使用"断开的管道"消息被提出。解决方法是将SIGPIPE重置为默认操作(另请参阅here)。

# test case
python -c 'import os; os.system("LANG=C date | false")'  # date: stdout: Broken pipe
python -c 'import os, signal; signal.signal(signal.SIGPIPE, signal.SIG_DFL); os.system("LANG=C date | false")'