如何使用子过程将Windows nslookup的输出过滤为仅显示名称?

问题描述 投票:1回答:2

我有一个在线找到的脚本并开始进行修改。它扫描网络中的主机,现在我希望它使用nslookup命令在IP 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 

作为输出。

**

感谢martineau,这是按照我的预期运行的固定代码:

**

# 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.')
python windows subprocess
2个回答
0
投票

[我不认为您可以像这样将命令行管道与Popen结合使用-但幸运的是,您实际上并不需要它,因为Python可以像Windows find命令一样轻松地进行文本处理。] >

这证明了我的意思:

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


0
投票

您只需要将子流程输出分配给变量并拆分。

© www.soinside.com 2019 - 2024. All rights reserved.