2013-02-13 112 views
3

情况: 我想通过sram和paramiko来远程登录远程日志。Paramiko/ssh/tail + grep挂起

channel.exec_command( '尾-f log.log')工作正常

channel.exec_command( '-f log.log尾| grep的 “过滤器”')挂

无法理解的原因尾巴与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

谢谢你“ - 线缓冲”的作品。 – 2013-02-15 20:04:07