Read file with timeout in Python

后端 未结 3 1566
甜味超标
甜味超标 2020-12-03 17:33

Within Linux, there is a file, /sys/kernel/debug/tracing/trace_pipe, which as the name says, is a pipe. So, let\'s say I want to read the first 50 bytes from it

相关标签:
3条回答
  • 2020-12-03 17:49

    Use

    os.read(f.fileno(), 50)
    

    instead. That does not wait until the specified amount of bytes has been read but returns when it has read anything (at most the specified amount of bytes).

    This does not solve your issue in case you've got nothing to read from that pipe. In that case you should use select from the module select to test whether there is something to read.

    EDIT:

    Testing for empty input with select:

    import select
    r, w, e = select.select([ f ], [], [], 0)
    if f in r:
      print os.read(f.fileno(), 50)
    else:
      print "nothing available!"  # or just ignore that case
    
    0 讨论(0)
  • 2020-12-03 17:50

    Just adding this as note, for better formatting:

    @Alfe's answer in my case:

    $ sudo python -c 'import os, select; 
    f=open("/sys/kernel/debug/tracing/trace_pipe","r"); print f; 
    rrdy, wrdy, xrdy = select.select([f], [], [], 1); print rrdy, wrdy, xrdy ; 
    timeout= "timed out" if (rrdy==[]) else "" ; 
    print timeout; 
    print os.read(f.fileno(), 50) if timeout=="" else ""; 
    f.close() '
    

    If there is something in the file, I get response like:

    <open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb76f0e90>
    [<open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb76f0e90>] [] []
    
                Xorg-1033  [001] 12570.075859: <user s
    

    If there is nothing in the file, I get:

    <open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb7831e90>
    [] [] []
    timed out
    

    Note that the select documentation isn't explicit that the timeout parameter is in seconds - but that floating point values (e.g. 0.5) also work.

    @GabiMe's answer:

    $ sudo python -c 'import os; 
    filno = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK); 
    f=os.fdopen(filno, "r"); print f; 
    print "A", f.read(50); 
    print "B", os.read(f.fileno(), 50); 
    f.close() '
    

    If there is something in the file, I get response like:

    <open file '<fdopen>', mode 'r' at 0xb77b6e90>
    A             bash-13777 [000] 13694.404519: sys_exi
    B            Timer-31065 [001] 13694.404830: sys_exi
    

    If there is nothing in the file, I get:

    <open file '<fdopen>', mode 'r' at 0xb77c1e90>
    A
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    IOError: [Errno 11] Resource temporarily unavailable
    

    ... so one must run this in a try block, to catch the IOError, if there is nothing in the file... (both os.read and f.read will raise this exception)

    0 讨论(0)
  • 2020-12-03 18:06
    f = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK)
    

    Should prevent blocking (works in Unix only).. No need for select here..

    0 讨论(0)
提交回复
热议问题