Как использовать подпроцесс для фильтрации вывода Windows nslookup только для отображения имени? - PullRequest
1 голос
/ 06 апреля 2020

У меня есть скрипт, который я нашел в сети и начал изменять. Он сканирует сеть на наличие хостов, и теперь я хочу использовать команду nslookup для отображения имени хоста в сообщении «IP is up».

Программа:

# Import modules
import subprocess
import ipaddress

# Prompt the user to input a network address
net_addr = input("Enter a network address in CIDR format(ex.192.168.1.0/24): ")

# Create the network
ip_net = ipaddress.ip_network(net_addr)

# Get all hosts on that network
all_hosts = list(ip_net.hosts())

# Configure subprocess to hide the console window
info = subprocess.STARTUPINFO()
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = subprocess.SW_HIDE

# For each IP address in the subnet, 
# run the ping command with subprocess.popen interface
for i in range(len(all_hosts)):
    output = subprocess.Popen(['ping', '-n', '1', '-w', '1', str(all_hosts[i])], stdout=subprocess.PIPE, startupinfo=info).communicate()[0]

    if "Destination host unreachable" in output.decode('utf-8'):
        None
    elif "Request timed out" in output.decode('utf-8'):
        None
    else:
        print(str(all_hosts[i]), "is Online",)
        #Runs nslookup for online host, need to figure how to filter it to just show name
        subprocess.Popen(['nslookup', str(all_hosts[i])])
print('Scan complete.')

В настоящее время это работает, но выводит весь вывод из nslookup.

В windows командной строке nslookup X.X.X.X | find /I "Name: ".

Дает мне то, что я хочу.

Я попытался добавить в качестве строки после ввода списка, но это не работает.

Я использовал shlex, чтобы разделить args, и попробовал это, но он дает мне инструкции о том, как использовать nslookup, когда я делаю.

Пример:

>>> command_line = input()
nslookup 8.8.8.8 | find /I "Name: "
>>> args = shlex.split(command_line)
>>> print(args)
['nslookup', '8.8.8.8', '|', 'find', '/I', 'Name: ']
>>> subprocess.Popen(['nslookup', '8.8.8.8', '|', 'find', '/I', 'Name: '])
<subprocess.Popen object at 0x03747208>
>>> Usage:
   nslookup [-opt ...]             # interactive mode using default server
   nslookup [-opt ...] - server    # interactive mode using 'server'
   nslookup [-opt ...] host        # just look up 'host' using default server
   nslookup [-opt ...] host server # just look up 'host' using 'server'

Есть ли простой способ для меня, чтобы просто получить имя?

Что бы я хотел, это

X.X.X.X is Online
Name: hostname from nslookup 

в качестве вывода.

**

Благодаря Мартино, вот фиксированный код, который работает так, как я планировал:

**

# Import modules
import subprocess
import ipaddress

# Prompt the user to input a network address
net_addr = input("Enter a network address in CIDR format(ex.192.168.1.0/24): ")

# Create the network
ip_net = ipaddress.ip_network(net_addr)

# Get all hosts on that network
all_hosts = list(ip_net.hosts())

# Configure subprocess to hide the console window
info = subprocess.STARTUPINFO()
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = subprocess.SW_HIDE

# For each IP address in the subnet, 
# run the ping command with subprocess.popen interface
for i in range(len(all_hosts)):
    output = subprocess.Popen(['ping', '-n', '1', '-w', '1', str(all_hosts[i])], stdout=subprocess.PIPE, startupinfo=info).communicate()[0]

    if "Destination host unreachable" in output.decode('utf-8'):
        None
    elif "Request timed out" in output.decode('utf-8'):
        None
    else:
        print(str(all_hosts[i]))
        #Runs nslookup for online host, prints the host name is online
        args =['nslookup', str(all_hosts[i])]
        completed = subprocess.run(args, stdout=subprocess.PIPE)
        onlineName = [line for line in completed.stdout.decode('utf-8').splitlines() if "Name: " in line]
        if onlineName:
            print(onlineName[0].split()[1], 'is Online \n')       
print('Scan complete.')

Ответы [ 2 ]

0 голосов
/ 06 апреля 2020

вам просто нужно присвоить выход подпроцесса переменной и разделить.

    # Import modules
    import subprocess
    import ipaddress

    # Prompt the user to input a network address
    net_addr = input("Enter a network address in CIDR format(ex.192.168.1.0/24): ")

    # Create the network
    ip_net = ipaddress.ip_network(net_addr)

    # Get all hosts on that network
    all_hosts = list(ip_net.hosts())

    # Configure subprocess to hide the console window
    info = subprocess.STARTUPINFO()
    info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    info.wShowWindow = subprocess.SW_HIDE

    # For each IP address in the subnet, 
    # run the ping command with subprocess.popen interface
    for i in range(len(all_hosts)):
        output = subprocess.Popen(['ping', '-n', '1', '-w', '1', str(all_hosts[i])], 
    stdout=subprocess.PIPE, startupinfo=info).communicate()[0]

        if "Destination host unreachable" in output.decode('utf-8'):
            None
        elif "Request timed out" in output.decode('utf-8'):
            None
        else:
            print(str(all_hosts[i]), "is Online",)
            #Runs nslookup for online host, need to figure how to filter it to just    show name
            process=subprocess.Popen(['nslookup', str(all_hosts[i])],stdout=subprocess.PIPE, universal_newlines=True)
            output=(process.communicate()[0])
            print(type(output))
            line=output.split("\n")
            print(line[0].split(":")[1], 'is online')


    print('Scan complete.')
0 голосов
/ 06 апреля 2020

Я не думаю, что вы можете выполнять конвейерную обработку командной строки в сочетании с Popen, но к счастью вам это не нужно, потому что Python может легко выполнять обработку текста, что Windows * 1002. * команда делает.

Это показывает, что я имею в виду:

import subprocess

args = ['nslookup', '8.8.8.8']
completed = subprocess.run(args, stdout=subprocess.PIPE)
online = [line for line in completed.stdout.decode('utf-8').splitlines() if "Name:" in line]
if online:
    print(online[0].split()[1], 'is online')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...