2014-10-10 2 views
1

Я хотел бы обработать вывод из запроса подпроцесса и распечатать только конкретные детали. Теперь я первоначально спускался по маршруту PIPE и прокладывал вывод на другой subprocessgrep, но это казалось слишком ограниченным, то есть я мог печатать только несколько строк (некоторые из которых мне не нужны), используя -A или -Bgrep аргументы. Итак, теперь я беру маршрут stdout.readline. Мой вопрос: есть ли лучший способ добиться того, что я пытаюсь сделать? Является ли соответствие шаблону регулярным выражениям и re лучшим вариантом?Обработка выходных данных из подпроцесса

Ниже приведен код для обоих путей мысли, чтобы дать некоторый контекст.

PIPE другого подпроцесс:

def nmap_ips(ip_list): 

    for ip in ip_list: 
     cmd1 = subprocess.Popen(["nmap", "-sC", "--open", "-Pn", "-p80,443", ip], stderr=subprocess.STDOUT, stdout=subprocess.PIPE) 
     cmd2 = subprocess.Popen(["grep", "title", "-A", "1"], stdin=cmd1.stdout) 
     cmd1.stdout.close() 
     output = cmd2.communicate()[0] 

стандартный вывод читать строки: #Im не на самом деле получить выход из этой функции в данный момент, я предполагаю, что это мое регулярное выражение

def nmap_ips(ip_list): 
    regs = ["title", "commonName"] 
    combined = "|".join(regs) 

    for ip in ip_list: 
     p = subprocess.Popen(["nmap", "-sC", "--open", "-Pn", "-p80,443", ip], stderr=subprocess.STDOUT, stdout=subprocess.PIPE) 
     for line in iter(p.stdout.readline, b''): 
     ml = re.match(combined, line) 
     if ml: 
      print ml.group() 

Пример данных, которые я пытаюсь манипулировать

Starting Nmap 6.40 (http://nmap.org) at 2014-10-10 23:47 BST 
Nmap scan report for BTHomeHub.home (192.168.1.254) 
Host is up (0.0054s latency). 
PORT STATE SERVICE 
80/tcp open http 
| http-title: Home Hub Manager - Please Reset Your Password 
|_Requested resource was http://BTHomeHub.home/html/home/a_firstlogin_configuration.html 
443/tcp open https 
| ssl-cert: Subject: commonName=bthomehub.home/countryName=UK 
| Not valid before: 2011-01-15T16:52:23+00:00 
|_Not valid after: 2024-01-17T16:52:23+00:00 
|_ssl-date: 2014-10-10T22:47:18+00:00; +14s from local time. 
+0

В чем вопрос? Вы видите требуемый вывод, если используете 'print line,'? Вам нужно отлаживать регулярное выражение? Затем удалите несвязанный код подпроцесса и просто укажите несколько строк как строки в самом коде как тестовый ввод. – jfs

+0

Извинения, похоже, я недостаточно прояснил ситуацию. Прежде всего, я прошу рекомендации о том, как добиться того, что мне нужно. Является ли метод readline возможным? – iNoob

+0

возможно для чего? Код читает строки 'b '\ n''-разделенные от объединенного stdout/stderr от nmap. Это то, что вам нужно? Каков ожидаемый результат? – jfs

ответ

0

Ваш подход прекрасен. И grep 'title\|commonName', и re.search(b'title|commonName', line) должны работать.

Примечание: re.match() начинает сопоставление в начале строки ввода. re.search() находит совпадение в любом месте строки.

Если вы хотите сохранить эти строки в переменной, то процесс grep не нужен. Достаточно начать только nmap.

from subprocess import Popen, PIPE, STDOUT 

def nmap_something(ip_list): 
    match = re.compile(b"title|commonName").search 
    p = Popen(["nmap", "-sC", "--open", "-Pn", "-p80,443"] + ip_list, 
       stdout=PIPE, stderr=STDOUT, bufsize=1) 
    result = list(filter(match, p.stdout)) 
    p.stdout.close() 
    p.wait() 
    return result 

Я не уверен, что точный синтаксис, чтобы передать несколько IP-адресов для одного процесса nmap ребенка, но он поддерживает это то, что вам не нужно запускать несколько процессов сканирования нескольких IP-адресов.

Если вы хотите распечатать сертификаты SSL для веб-серверов, то вам не нужно nmap, вы могли бы использовать чистый Python решение, например, см How to get server's ssl certificate in a human readable form?

+0

Прохождение IP-адресов не является проблемой, и все работает нормально. Я не использую 'grep' в повторном подходе. 'grep' будет использоваться, если я спустил начальную' PIPE' на другой 'subprocess' (был бы grep). – iNoob

+0

Использование 're.search' Я получаю вывод, но это только точное совпадение, которое напечатано. Lol IE' title' next line 'commonName' – iNoob

+0

Ok ive получил его работу. Вместо печати соответствующей группы. Я просто печатаю строку 'if ml:' – iNoob

0

После некоторого совета от JFSebastian, я изменил re.search и нашел печать линии напрямую достигнута, что я был после.

def nmap_ips(ip_list): 
    regs = ["title", "commonName"] 
    combined = "|".join(regs) 

    for ip in ip_list: 
     p = subprocess.Popen(["nmap", "-sC", "--open", "-Pn", "-p80,443", ip], stderr=subprocess.STDOUT, stdout=subprocess.PIPE) 
     for line in iter(p.stdout.readline, b''): 
      ml = re.search(combined, line) 
      if ml: 
       print line 
Смежные вопросы