How do you read from stdin in python from a pipe which has no ending

后端 未结 5 1789
春和景丽
春和景丽 2020-12-02 23:35

I\'ve problem to read from Standard input or pipe in python when the pipe is from a \"open\" (do not know right name) file.

I have as example pipetest.py:

相关标签:
5条回答
  • 2020-12-02 23:39

    For this to work without waiting until the stdin stream ends, you can iter on the readline. I think this is the simplest solution.

    import sys
    k = 0
    try:
       for line in iter(sys.stdin.readline, b''):
          k = k + 1
          print line
    except KeyboardInterrupt:
       sys.stdout.flush()
       pass
    print k
    
    0 讨论(0)
  • 2020-12-02 23:46

    This is how I ended up doing this. I didn't really like any of the other solutions, they didn't seem very pythonic.

    This will make a container for any open file input to iterate over all the lines. This will also take care of closing the file at the end of the context manager.

    I feel like this is probably how the for line in sys.stdin: block should operate by default.

    class FileInput(object):                                                        
        def __init__(self, file):                                                   
            self.file = file                                                       
    
        def __enter__(self):                                                        
            return self                                                             
    
        def __exit__(self, *args, **kwargs):                                        
            self.file.close()                                                       
    
        def __iter__(self):                                                         
            return self                                                             
    
        def next(self):                                                             
            line = self.file.readline()                                             
    
            if line == None or line == "":                                          
                raise StopIteration                                                 
    
            return line  
    
    with FileInput(sys.stdin) as f:
        for line in f:
            print f
    
    with FileInput(open('tmpfile') as f:
        for line in f:
            print f
    

    From the command line both of the following should work:

    tail -f /var/log/debug.log | python fileinput.py
    cat /var/log/debug.log | python fileinput.py
    
    0 讨论(0)
  • 2020-12-02 23:58

    while sys.stdin is a file-like object, meaning you can iterate over its lines, it will block until a EOF is inserted.

    The behaviour can be described with the following pseudo-code:

    while True:
        input = ""
        c = stdin.read(1)
        while c is not EOF:
            input += c
            c = stdin.read(1)
        for line in input.split('\n'):
            yield line
    

    this means that, while you can iterate over sys.stdin's lines, you cannot use this approach for the task at hand and you must explicitly call read() or readline()

    0 讨论(0)
  • 2020-12-02 23:59

    Try the next:

    import sys
    import time
    k = 0
    try:
        buff = ''
        while True:
            buff += sys.stdin.read(1)
            if buff.endswith('\n'):
                print buff[:-1]
                buff = ''
                k = k + 1
    except KeyboardInterrupt:
       sys.stdout.flush()
       pass
    print k
    
    0 讨论(0)
  • 2020-12-02 23:59
    k = 0
    try:
        while True:
            print sys.stdin.readline()
            k += 1
    except KeyboardInterrupt:
        sys.stdout.flush()
        pass
    print k
    
    0 讨论(0)
提交回复
热议问题