2013-02-13 2 views
3

Ситуация: Я хочу хвост удаленных журналов через ssh с paramiko.Paramiko/ssh/tail + grep hang

channel.exec_command ('Tail -f log.log') работает отлично

channel.exec_command ('хвост -f log.log | Grep "фильтр"') вешает

Не могу понять причину, почему хвост с грифом висит.

Пример кода:

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() 

ответ

6

grep считает, что он не пишет на терминал, так что буферные его выход. Недостаточно строк его ввода подходят для того, чтобы написать любой из его выходных данных, поэтому вы считаете, что он повесился.

Попробуйте дать grep--line-buffered вариант. например

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

спасибо, что работает «-line-buffered». –