使用 Bash 解析 dhcpd.lease 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2142824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:35:27  来源:igfitidea点击:

Parse a dhcpd.lease File with Bash

bashparsinggrep

提问by fwaechter

I Try to parse my dhcpd.lease File with Basel. A typical entry looks like this:

我尝试用巴塞尔解析我的 dhcpd.lease 文件。典型的条目如下所示:

lease 192.168.20.4 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
    uid 00:00:00:00:00:00;
    client-hostname "examle-workstation1";
}

All information i get is the MAC and what i want ist the IP and the client-hostname. But maybe, there is no client-hostname. The entry looks like this:

我得到的所有信息都是 MAC,我想要的是 IP 和客户端主机名。但也许,没有客户端主机名。该条目如下所示:

lease 192.168.20.5 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
}

My first idea was to grep the lease attribute, the hardware ethernet attribute and the uid attribute and putt it all on one line. And then parse it.

我的第一个想法是 grep 租用属性、硬件以太网属性和 uid 属性,并将它们全部放在一行上。然后解析它。

But my problem is, i have a big file with many entries allocated in many files. The tree looks like this:

但我的问题是,我有一个大文件,在许多文件中分配了许多条目。这棵树看起来像这样:

dhcpd-leases
-- 192.168.20.0
-- 192.168.30.0
-- 192.168.40.0
[...]

And all what i get ist the MACs parsed from another files in to a list. So i start with this list and want to grep the Attributes ip, mac with my MAC:

我得到的所有东西都是从另一个文件解析到列表中的 MAC。所以我从这个列表开始,想用我的 MAC 来 grep 属性 ip, mac:

for ENTRY in $MACLIST
do
    VAR$(cat "dhcpd-leases/10.148.$NETWORK.2/dhcpd.leases" | grep -E "$MAC|lease|client-hostname")
    echo $VAR
done

But it because of the many entrys in the $VAR and the files im unable to Parse it out right.

但这是因为 $VAR 中的许多条目和文件我无法正确解析它。

Can somenone help?

有人可以帮忙吗?

Best regards Peter

最好的问候彼得

采纳答案by ghostdog74

assuming your maclist file look like this (just one entry for example)

假设您的 maclist 文件如下所示(例如,只有一个条目)

$ cat maclist
00:00:00:00:00:01

and your lease file like this

和你的租约文件是这样的

$ cat file
lease 192.168.20.4 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
    uid 00:00:00:00:00:00;
    client-hostname "examle-workstation1";
}

lease 192.168.20.5 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
}

lease 192.168.20.6 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:01;
    uid 00:00:00:00:00:01;
    client-hostname "examle-workstation2";
}


lease 192.168.20.7 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 01:00:00:00:00:00;
}

you can try this

你可以试试这个

awk 'BEGIN{
    while( (getline line < "maclist") > 0){
        mac[line]
    }
    RS="}"
    FS="\n"
}
/lease/{
    for(i=1;i<=NF;i++){
        gsub(";","",$i)
        if ($i ~ /lease/) {
            m=split($i, IP," ")
            ip=IP[2]
        }
        if( $i ~ /hardware/ ){
            m=split($i, hw," ")
            ether=hw[3]
        }
        if ( $i ~ /client-hostname/){
            m=split($i,ch, " ")
            hostname=ch[2]
        }
        if ( $i ~ /uid/){
            m=split($i,ui, " ")
            uid=ui[2]
        }
    }
    if ( ether in mac ){
        print "ip: "ip " hostname: "hostname " ether: "ether " uid: "uid
    }
} ' file

output

输出

$ ./shell.sh
hostname: "examle-workstation2" ether: 00:00:00:00:00:01 uid: 00:00:00:00:00:01

回答by bigmac

I like awk, but I like it less when the program gets big.

我喜欢 awk,但是当程序变大时我不太喜欢它。

So I found another way of parsing the leases file, finding first a unix command chain that converts the file into a two columns format, the ip adress in the first column, the mac address in the second:

所以我找到了另一种解析leases文件的方法,首先找到一个unix命令链,将文件转换成两列格式,第一列是ip地址,第二列是mac地址:

cat dhcpd.leases |  egrep -o 'lease.*{|ethernet.*;' | awk '{print }' | xargs -n 2 | cut -d ';' -f 1

with a simple awk command you can then get the ip address from the mac address. Following here is the full command built as a shell function:

使用简单的 awk 命令,您就可以从 mac 地址获取 IP 地址。以下是作为 shell 函数构建的完整命令:

function f_mac_to_ip {

parseResult=$(cat /var/lib/dhcp/db/dhcpd.leases |  egrep -o 'lease.*{|ethernet.*;' | awk '{print }' | xargs -n 2 | cut -d ';' -f 1  | grep  | awk '{print }')
    echo "$parseResult"
}

I don't know much about the leases format. If ever there can be entries without an "ethernet" field, the above parsing wouldn't work.

我不太了解租约格式。如果可以有没有“以太网”字段的条目,则上述解析将不起作用。

回答by t0mm13b

If you are trying to get the MAC's and IP's, it would be better to use the arp -scommand instead of looking at the DHCP lease file.

如果您尝试获取 MAC 和 IP,最好使用该arp -s命令而不是查看 DHCP 租用文件。

回答by Beau

Text::DHCPLeaseswould also do exactly what you need, without reinventing the wheel. :)

Text::DHCPLeases也可以完全满足您的需求,而无需重新发明轮子。:)

回答by Benoit Duffez

Not necessarily better than @ghostdog74, but here's a script to convert to json:

不一定比@ghostdog74 好,但这里有一个转换为 json 的脚本:

#!/usr/bin/awk -f

# Start with array creation
BEGIN {
    printf "[";
}

# New lease: start object 
/^lease/ {
    # If that ip is unknown, create a new JSON object
    if (!known[]) {
        # if this object is not the first, print a comma
        if (!notFirst) {
            notFirst=1;
        } else {
            printf ",";
        }

        # create a new JSON object with the first key being the IP (column 2)
        printf "{\"ip\":\"%s\"", ; known[]=1;

        # print subsequent lines, see below
        p=1;
    }
}

# If printing is enabled print line as a JSON key/value pair
p && /^  / {
    # Print key (first word)
    printf ",\"%s\":", ;

    # Clean up the rest of the line: trim whitespace and trailing ;, remove " and escape \
    ="";
    gsub(/\/, "\\", 
$ /opt/dhcpd.leases_to_json.awk /var/lib/dhcp/dhcpd.leases | jq .
[
  {
    "ip": "10.7.37.10",
    "starts": "3 2019/08/28 22:24:26",
    "ends": "3 2019/08/28 22:34:26",
    "cltt": "3 2019/08/28 22:25:32",
    "binding": "state active",
    "next": "binding state free",
    "rewind": "binding state free",
    "hardware": "ethernet xx:xx:xx:xx:xx:xx",
    "client-hostname": "zzzzzzz"
  },
  {
    "ip": "10.7.37.11",
    "starts": "3 2019/08/28 22:26:10",
    "ends": "3 2019/08/28 22:36:10",
    "cltt": "3 2019/08/28 22:26:10",
    "binding": "state active",
    "next": "binding state free",
    "rewind": "binding state free",
    "hardware": "ethernet xx:xx:xx:xx:xx:xx",
    "uid": "\001pv\377\001\005~",
    "client-hostname": "xxxx"
  }
]
); gsub(/"/, "", ##代码##); gsub(/^[\t ]*/, "", ##代码##); gsub(/;$/, "", ##代码##); printf "\"%s\"", ##代码##; } # End of lease: close JSON object and disable printing /^\}$/ { if (p) { printf "}" } p=0 } # Close the JSON array END { print "]"; }

Result:

结果:

##代码##