免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5238 | 回复: 6
打印 上一主题 下一主题

os.system(sort)疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-23 19:09 |只看该作者 |倒序浏览
python程序需要调用如下的sort命令:

sort -t@ -rink1 /data1/admatch//datamanager/logAna//his//maxRate/stats/20080523/1_max_rate.dat.tmp -T /data2/search/.SortTmp/|head -n100 > /data1/admatch//datamanager/logAna//his//maxRate/stats/20080523/1_max_rate.dat

python执行的时候经常会输出如下的错误:
sort: write failed: -: Broken pipe

其中,1_max_rate.dat.tmp  117KB
不知道为什么会出现这个错误;如果我在shell手动调用这个sort命令,则不会出现错误。
先谢谢各位了!

论坛徽章:
0
2 [报告]
发表于 2008-05-26 10:55 |只看该作者
up一下!呵呵

论坛徽章:
0
3 [报告]
发表于 2008-05-27 15:05 |只看该作者
看到你在shell版发的帖子,发出了这样的感慨:
但我个人觉得:如果在shell脚本里遇到,数据量大,计算量也大的应用的时候,最好不要使用管道。存成临时文件会更安全
和强壮些。(个人想法,欢迎批评指正!)
其实这并不是管道的问题,使用管道反而会提高效率,就拿你的例子来说sort file |head -n 100,如果file这个文件很大,而head只需要前100行就够了,何必要把整个文件的内容都写入管道呢,这不是多此一举嘛。
对于管道来说写一个读断已经关闭的管道,会产生SIGPIPE信号,在这里head读完100行之后就结束了,sort再往管道里面写就会接收到SIGPIPE信号,而sort是不会显示的处理信号的。在一个程序刚启动时,会把在父进程中设置为捕捉的信号,设置为默认动作,设置为忽略的不做改变。在登录shell中对于SIGPIPE的动作是默认动作,也就是进程结束。所以在终端下执行sort这个命令接收到SIGPIPE信号时,进程就直接退出了,所以不会产生出错信息。当然也不是正常结束的,只不过你看不到出错信息罢了。而python启动后,则会把SIGPIPE设置为忽略。在sort进程中接收到此信号时,也会忽略这个信号,继续执行。然后sort发现write的返回值为-1,就认为产生了错误,所以会打印出错信息。
你可以做一个实验,在python中import singal,然后signal.singal(signal.SIGPIPE,signal.SIG_DFL),把SIGPIPE设置为默认动作,然后再执行sort命令,你就不会看到出错信息了。

论坛徽章:
0
4 [报告]
发表于 2008-05-27 22:55 |只看该作者
原帖由 ocean390 于 2008-5-27 15:05 发表
看到你在shell版发的帖子,发出了这样的感慨:
但我个人觉得:如果在shell脚本里遇到,数据量大,计算量也大的应用的时候,最好不要使用管道。存成临时文件会更安全
和强壮些。(个人想法,欢迎批评指正!)
...


收藏。

不妨用os.popen().readline 读100行出来。

论坛徽章:
0
5 [报告]
发表于 2008-05-28 17:50 |只看该作者
ocean390的分析十分到位!
兄弟我学到很多东西!多谢!我当时咋就没想出来呢!
难怪我当时在分析生成的文件的时候,发现结果是正确的。
另外从分析中我也觉得,利用broken pipe,也正是使用管道以提高效率的原因之一。

如此精辟之分岂能独享!再up一下!

save as...

论坛徽章:
0
6 [报告]
发表于 2008-05-29 11:46 |只看该作者
原帖由 fufeiwxy 于 2008-5-28 17:50 发表
ocean390的分析十分到位!
兄弟我学到很多东西!多谢!我当时咋就没想出来呢!
难怪我当时在分析生成的文件的时候,发现结果是正确的。
另外从分析中我也觉得,利用broken pipe ...







  1. import os
  2. import sys
  3. import time
  4. import traceback

  5. fifoname = '/tmp/pipefifo' # must open same name

  6. def child():
  7.         pipeout= os.open(fifoname, os.O_WRONLY) # open fifo pipe file as fd
  8.         zzz = 0
  9.         while True:
  10.                 try:
  11.                         time.sleep(zzz)
  12.                         os.write(pipeout, 'Spam %03d\n' % zzz)
  13.                 except OSError:
  14.                         exc_info = sys.exc_info()
  15. #                        print exc_info[0]
  16.                         print exc_info[1]
  17. #                        traceback.print_tb(exc_info[2])
  18.                         if str(exc_info[1])[-11:].lower() == 'broken pipe':
  19.                                 print 'Consumer had exited...'
  20.                                 lets_exit()
  21.                 except KeyboardInterrupt:
  22.                         os.write(pipeout,'Byebye\n')
  23.                         print 'Byebye message had sent...'
  24.                         lets_exit()
  25.                 else:
  26.                         zzz = (zzz+1) %5

  27. def lets_exit():
  28.         print 'OK, byebye'
  29.         sys.exit()


  30. def parent():
  31.         pipein = open(fifoname, 'r') # open fifo as stdio object
  32.         while True:
  33.                 try:
  34.                         line = pipein.readline()[:-1] # block until data sent
  35.                         if line:
  36.                                 print 'Parent %d got "%s" at %s' % (os.getpid(), line, time.time())
  37.                                 if line[:3].lower() == 'bye':
  38.                                         print 'Proceduer had exited...'
  39.                                         lets_exit()
  40.                 except  KeyboardInterrupt:
  41.                                 lets_exit()

  42. if __name__ == '__main__':
  43.         if not os.path.exists(fifoname):
  44.                 os.mkfifo(fifoname) # create a named pipe file
  45.         if len(sys.argv) == 1: # run as parent if no args
  46.                 parent()
  47.         else: # else run as child process
  48.                 child()
复制代码

论坛徽章:
0
7 [报告]
发表于 2008-05-29 21:18 |只看该作者

回复 #6 baif 的帖子

不太清楚要说明什么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP