从 python3 中的 bash 执行 DNS 查询的最佳方式是什么?

What would be an optimal way to perform DNS query from bash in python3?

我有一个简单的 bash 脚本,我正在考虑将其合并到我的 python 项目中,因为我无法在 python3 中找到一种优雅的方式来执行此操作与这个单一的 bash oneliner 相比。在 python3 或有助于将所有合法的唯一主机名存储在列表或字典中的库中,是否有更好的方法来执行此操作?

我尝试按照以下方式做一些事情,

test = []
try:
    with open("dig.log", "r") as d:
        for line in d:
            parsed_lines = line.rstrip()
            if not parsed_lines.startswith(";"):
                test.append(parsed_lines.split())
except FileNotFoundError as fnf_error:
    print(fnf_error)

输出,


10.10.10.10.in-addr.arpa. 604800 IN     PTR     ns1.yowhat.sup

10.10.10.in-addr.arpa.  604800  IN      NS      ns1.yowhat.sup

ns1.yowhat.sup.         604800  IN      A       10.10.10.10    

有一堆空行。我无法弄清楚如何优雅地去除()所有空白行,只去除 return python 中的唯一主机名。 我可以使用单个 bash oneliner 获得确切的功能,如下所示:

grep -v ";" $dig_file | sed 's/\.$//g' | sed -r '/^\s*$/d' | sed -n -e 's/^.*PTR\t//p; s/^.*NS\t//p; s/^.*MX\t//p; s/^.*CNAME\t//p; s/^.*TXT\t//p' | sort -u >$output_file_name

哪个会输出,

ns1.yowhat.sup

到一个文件。 我在我的 python 程序中使用的助手 bash 脚本是,

#!/usr/bin/env bash

dig_file=
output_file_name=
NICE='\e[1;32;92m[+]\e[0m'

parse_dig() {
    echo -e "${NICE} parsing dig queries to find hostnames ya dig?"
    grep -v ";" $dig_file | sed 's/\.$//g' | sed -r '/^\s*$/d' | sed -n -e 's/^.*PTR\t//p; s/^.*NS\t//p; s/^.*MX\t//p; s/^.*CNMAE\t//p; s/^.*TXT\t//p' | sort -u >$output_file_name
}
parse_dig

然后我会在我的 python 项目中调用它做类似的事情,

subprocess.call("./parse_dig dig.log host_names.log", shell=True)

我如何做我的简单 bash 脚本帮助程序脚本在 python3 中所做的,而不需要使用一堆 bash 脚本来解析文件的输出? 不使用

会更有意义吗
subprocess.call("dig command | tee dig.log" , shell=True)

然后做一些事情,

dig_output = subprocess.check_call("dig command...", shell=True, STDERR=subprocess.STDOUT)

然后以某种方式解析 python 中的 dig_output 或者什么是最优雅的,pythonic,在 python3 中执行此操作的理想方法?

您需要从 python 运行 dig 获取输出:

from subprocess import PIPE, Popen

def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    )
    return process.communicate()[0]

之后事情就变得很简单了:

>>> dig_output = [i.strip() for i in cmdline( 'dig google.com ns' ).split('\n')] 
>>> dig_filtered = [i.split() for i in dig_output if len(i) > 10]
>>> domains = [i[-1] for i in dig_filtered if i[-2] in ['PTR', 'MS', 'NS', 'CNAME', 'TXT']]
>>> domains
['ns1.google.com.', 'ns2.google.com.', 'ns4.google.com.', 'ns3.google.com.']
>>>