zoukankan      html  css  js  c++  java
  • for line in sys.stdin

    绚丽也尘埃 » for line in sys.stdin

    for line in sys.stdin

    纠结一个下午和一个晚上了,我想在syslog-ng里面添加一个program destination,程序是用Python写的,结果发现file destination总是在第一时间就能收到消息,而program则没有什么动静,反复测试了好多遍都是如此。man Python,发现了Python有个’-u’参数,man是这样说的。

    -u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, std-out and stderr in binary mode. Note that there is internal buffering in xreadlines(), readlines() and file-object iterators (“for line in sys.stdin”) which is not influenced by this option. To work around this, you will want to use “sys.stdin.readline()” inside a “while 1:” loop.

    加上’-u’之后,标准输出打印的内容很快能进入日志文件中,标准输入还是没有动静。当时没有仔细看这段说明,里面已经指出了for line in sys.stdin并不受影响,而我的代码偏偏是这样从标准输入里面读数据的。后来无意中在stackoverflow发现有一个人说这样迭代方式需要等到EOF出现才会开始执行,如果使用sys.stdin.readline()就不会有问题,测试了下发现果然是好用的。

    下面两个例子可以说明问题。在终端中分别运行两个程序,第一种遍历方式会等到敲入CRTL+D才会打印输入的内容。第二种方式输入一行,回车之后就会打印这行。

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    #!/bin/env
     
    import sys
     
    for line in sys.stdin:
        print line,
     
    line = sys.stdin.readline()
    while line:
        print line,
     
        line = sys.stdin.readline()

    奇怪的是,我写Hadoop Streaming Job时,一直都用for line in sys.stdin这种方式遍历,也没有出过问题。Hadoop Streaming官方文档里面的例子用的是readline这种方法。我猜这个应该是Hadoop的数据都保存在本地了,等于用cat的方式给脚本送数据,所以没有问题。

    在网上查资料的时候还发现有人反馈Python使用for line in sys.stdin的一个bug:Issue1633941,就是需要输入两次CRTL+D程序才会退出。Ralph Corderoy指出这个和Python 2.6用fread导致的问题,大概的意思是fread读到的数据长度为0时,它才认为获取到了EOF。如果没有得到指定长度的数据,即使数据后面存在EOF,它也会忽略。解决办法是在循环内使用feof对stdin进行一次判断,如果结束了就立即退出。

  • 相关阅读:
    mongodb备份与恢复
    MongoDB-3.4安装文档
    (转)Zabbix 3.2.7编译安装记录
    (转)error while loading shared libraries:libmysqlclient.so.18 错误
    (转)如何使用Journalctl查看并操作Systemd日志
    (转)基于CentOS 7安装Zabbix 3.4和Zabbix4.0
    (转)yum安装MariaDB(使用国内镜像快速安装,三分钟安装完毕)
    (转)nmon和nmon analyser的下载和使用
    (转)Db2 数据库常见堵塞问题分析和处理
    (转)我是一个线程
  • 原文地址:https://www.cnblogs.com/lexus/p/2467837.html
Copyright © 2011-2022 走看看