подпроцесс запускает команду до первого канала, затем останавливается

Если я запускаю эту команду самостоятельно:

nmap -PN -p 22 --open -oG - 10.15.86.0/24 | awk '$NF~/ssh/{print$2}' > sshopen.txt

Я получаю желаемый результат:

10.15.86.4
10.15.86.5
10.15.86.9
10.15.86.11
etc...

Все хосты в моей сети с открытым портом ssh. Однако, когда я пытаюсь запустить ту же команду в подпроцессе Python, кажется, что она пропускает awk. Питон ниже:

import subprocess

subnet = raw_input("Enter subnet to scan: ")
command1 = "nmap -PN -p 22 --open -oG - 10.15.86.0/24 | awk '$NF~/ssh /{print$2}' > sshopen.txt".split()
#command = ["nmap", "-PN", "-p", "22", "--open", "-oG", "-", subnet, "|", "awk", "'$NF~/ssh/{print $2}'", ">", "sshopen.txt"]
nmap = subprocess.Popen(command1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
nmap_info, out = nmap.communicate()  
print nmap_info

Вы заметите закомментированную «команду», так как я пробовал как «команда» и «команда1». Оба возвращают вывод:

Host: 10.15.86.4 () Status: Up
Host: 10.15.86.4 () Ports: 22/open/tcp//ssh///
Host: 10.15.86.5 () Status: Up
Host: 10.15.86.5 () Ports: 22/open/tcp//ssh///
etc...

Он выводит так, как будто канала awk нет (nmap -PN -p 22 --open -oG - 10.15.86.0/24), а не (nmap -PN -p 22 --open -oG - 10.15.86.0/24 | awk '$NF~/ssh/{print$2}' > sshopen.txt). Почему он не применяет awk в скрипте?

Спасибо


person cootermelon    schedule 21.08.2017    source источник
comment
Вы пытаетесь втиснуть две отдельные команды (nmap и awk) в один вызов Popen(), а это работает не так. Смотрите ответ @delta ниже.   -  person John Gordon    schedule 22.08.2017
comment
Ах, хорошо. Я думал, что вы можете рассматривать Popen() как один гигантский лайнер, если он правильно выполняется сам по себе как bash. Имеет смысл. Спасибо!   -  person cootermelon    schedule 22.08.2017


Ответы (1)


Пытаться

p1 = Popen(["nmap", "-PN", "-p", "22", "--open", "-oG", "-", subnet], stdout=PIPE)
p2 = Popen(["awk", "$NF~/ssh/{print$2}"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()
output = p2.communicate()[0]

or

check_output(command, shell=True)

Это из официального документа по подпроцессу python.

Однако есть некоторые соображения безопасности с shell=True.

В отличие от некоторых других функций popen, эта реализация никогда не будет неявно вызывать системную оболочку. Это означает, что все символы, включая метасимволы оболочки, можно безопасно передавать дочерним процессам. Если оболочка вызывается явно через shell=True, приложение несет ответственность за то, чтобы все пробелы и метасимволы были заключены в кавычки надлежащим образом, чтобы избежать уязвимостей внедрения оболочки.


  1. https://docs.python.org/3/library/subprocess.html#replacing-shell-pipeline
  2. https://docs.python.org/3/library/subprocess.html#security-considerations
person delta    schedule 22.08.2017