让python程序通过管道接收数据

2020年2月19日 / 28次阅读 / Last Modified 2020年2月19日

不是很确定本文的名称是否够准确,我的意思是,我想记录一下如何让python程序能够通过命令行的管道来接收数据,就像我们用管道符号(|)连接多个程序一样,前一个程序的输出对接后一个程序的输入,其中有一个是你的python程序。

管道数据来自stdin,通过sys模块,我们可以访问stdin对象,即sys.stdin。

跟读取文件的方法一样,sys.stdin也有read,readline,readlines这几个函数

基本思路是:在程序中读取sys.stdin中的内容,这就是通过管道过来的数据!(其实通过input函数接收的数据,也可以在sys.stdin中读取,不过这是程序的交互过程;而通过管道,是在程序启动的时候,数据就已经准备好了;管道也无法解决程序交互过程的输入)

在写代码验证的时候,遇到了一个小问题:sys.stdin.read()函数默认是阻塞的,而如果程序不结束,就不会出现EOF,程序就在read函数这里死等了。因此,要将read函数设置为非阻塞的方式,用fcntl模块的接口。

整个可运行的代码如下:

$ cat py_stdin.py 
import os
import sys
import fcntl


fcntl.fcntl(sys.stdin, fcntl.F_SETFL, os.O_NONBLOCK)
try:
    cc = sys.stdin.read()
except TypeError as e:
    print('no std input readed')
else:
    print(type(cc))
    print(len(cc))
    print(cc)

以非阻塞的方式调用read函数,如果stdin没有任何输入,会出现一个TypeError,因此使用了try...except...

运行效果:

$ echo -ne 'abcde\n12345' | python3.8 py_stdin.py 
<class 'str'>
11
abcde
12345
$ echo 'here goes to file' > test.txt
$ cat test.txt
here goes to file
$ python3.8 py_stdin.py < test.txt
<class 'str'>
18
here goes to file

一切看起来都很完美!

-- EOF --

本文链接:https://www.pynote.net/archives/1810

相关文章

    留言区

    《让python程序通过管道接收数据》有1条留言

    电子邮件地址不会被公开。 必填项已用*标注

    • 麦新杰

      本文中的代码,将sys.stdin.read()替换为sys.stdin.readlines(),即可避免stdin为空时的异常,此时得到的将是一个空list([]) [回复]


    前一篇:
    后一篇:

    More


    ©Copyright 麦新杰 Since 2019 Python笔记

    go to top