Paramiko / ssh / tail + grep hangs

Situation: I want to tail the remote logs over ssh with paramiko.

channel.exec_command ('tail -f log.log') works fine

channel.exec_command ('tail -f log.log | grep "filter") hangs

Can't figure out why the tail with grep is hanging.

Sample code:

import paramiko
import select
import re

interesting_line_pattern = re.compile('xxx')

def do_tail():
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    from os.path import expanduser
    home = expanduser("~")
    client.connect('xxx',
                   username='xxx',
                   key_filename='%s/.ssh/id_rsa' % home)

    log_file = '/home/xxx/log.log'
    grep_pattern = "grep_filter"
    remote_command = 'tail -f %s | grep "%s" ' % (log_file, grep_pattern)
    print remote_command

    transport = client.get_transport()
    channel = transport.open_session()
    channel.exec_command(remote_command)

    while 1:
        try:
            rl, _, _ = select.select([channel], [], [], 0.0)
            if len(rl) > 0:
                print "ready to read"
                for line in linesplit(channel):
                    print line

        except (KeyboardInterrupt, SystemExit):
            print 'got ctrl+c'
            break

    client.close()
    print 'client closed'

def linesplit(socket):
    buffer_string = socket.recv(4048)
    done = False
    while not done:
        if "\n" in buffer_string:
            (line, buffer_string) = buffer_string.split("\n", 1)
            yield line + "\n"
        else:
            more = socket.recv(4048)
            if not more:
                done = True
            else:
                buffer_string = buffer_string + more
    if buffer_string:
        yield buffer_string


if __name__ == '__main__':

    do_tail()

      

+3


source to share


1 answer


grep

thinks it is not writing to the terminal, so it buffers its output. There aren't enough lines of his input to write any of his output, so you think he's hung himself.

Try to give a grep

parameter --line-buffered

. eg.



channel.exec_command('tail -f log.log | grep --line-buffered "filter" ')

      

+6


source







All Articles