linux sed 查询 ip 及 mac

本文详细解读了两个命令行实例,展示了如何使用sed脚本从ifconfig和ipaddr输出中提取IPv4(inet),IPv6(inet6),和MAC地址(ether)。通过实例演示,读者可掌握如何针对不同网络配置获取所需信息。

示例1:

命令:

ifconfig | sed -e 's/^.*\(inet\|inet6\|ether\) \([^ ]*\).*$/\1 \2/;t;d'

 执行结果:

inet 10.10.33.155
inet6 fe80::10f2:a610:2fa:8752
inet6 2001:250:4000:2000::d70
ether 00:0c:29:ce:c1:2f
inet 127.0.0.1
inet6 ::1
inet 192.168.122.1
ether 52:54:00:ec:09:84

示例2:

命令:

ip addr | sed -e 's/^.*\(inet\|ether\|inet6\) \([^ /]*\).*$/\1 \2/;t;d'

 执行结果:

inet 127.0.0.1
inet6 ::1
ether 00:0c:29:ce:c1:2f
inet 10.10.33.155
inet6 2001:250:4000:2000::d70
inet6 fe80::10f2:a610:2fa:8752
ether 52:54:00:ec:09:84
inet 192.168.122.1
ether 52:54:00:ec:09:84

解析:

结果中 inet就是ipv4,inet6是ipv6,ether就是mac,sed脚本命令中s是寻找后面正则表达式的匹配并分组替换为匹配组的组1加空格加组2的内容,并在匹配成功后删除到匹配模板的中间行,保留查找替换成功的行,输出内容就是前面的示例,根据需要可以自行修改查询命令

<think>我们正在回答用户关于"在Linux系统中获取IP地址并排除环回地址的方法"的问题。 根据用户提供的引用资料和之前的回答,我们可以总结以下方法: 方法1:使用`hostname`命令(推荐) - `hostname -I` 会列出所有非回环的网络接口的IPv4和IPv6地址(以空格分隔),但不包括127.0.0.1(环回地址)[^1][^3]。 - 所以这个方法本身就排除了环回地址。 方法2:使用`ip`命令 - 我们可以使用`ip addr show`命令,然后过滤出inet(IPv4)或inet6(IPv6)的地址,并排除环回接口(通常为lo)和环回地址。 - 例如,获取IPv4地址并排除环回地址ip -4 addr show | grep -v "lo" | grep -oP '(?<=inet\s)\d+(\.\d+){3}' 解释: `ip -4 addr show`:显示所有IPv4地址信息 `grep -v "lo"`:排除环回接口(lo接口) `grep -oP '(?<=inet\s)\d+(\.\d+){3}'`:使用正则表达式提取IP地址 方法3:使用`ifconfig`命令(传统方法,需要安装net-tools) - 类似地,我们可以排除lo接口和环回地址ifconfig | grep -v "lo" | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' 方法4:使用C程序(如引用[3]中的示例) - 在遍历网络接口时,排除接口名为"lo"的接口即可(如代码中的`strcmp(ifa->ifa_name, "lo") != 0`)。 方法5:使用Python - 我们可以编写一个简单的Python脚本来获取IP地址并排除环回地址。例如: ```python import socket import netifaces # 排除回环接口 for interface in netifaces.interfaces(): if interface == 'lo': continue addresses = netifaces.ifaddresses(interface) if netifaces.AF_INET in addresses: for link in addresses[netifaces.AF_INET]: print(f"Interface {interface}: IPv4 Address: {link['addr']}") ``` 注意:上面的Python示例使用了`netifaces`模块,需要先安装(`pip install netifaces`)。 根据以上方法,我们给出以下建议: | 方法 | 命令/代码 | 特点 | |------|----------|------| | `hostname`命令 | `hostname -I` | 最简单快捷,直接排除环回地址,推荐在脚本中使用 | | `ip`命令 | `ip -4 addr show | grep -v "lo:" | grep -oP '(?<=inet\s)\d+(\.\d+){3}'` | 需要安装`iproute2`(现代Linux系统默认安装) | | `ifconfig`命令 | `ifconfig | grep -v "lo" | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*'` | 需要安装`net-tools`,输出格式可能因系统而异 | | Python程序 | 如上示例 | 适合在Python环境中使用,需要安装`netifaces`模块 | 注意:在脚本中使用时,注意处理多个网卡的情况以及没有IP地址的情况。 下面我们详细说明每种方法的步骤: ### 方法1:使用 `hostname` 命令 ```bash hostname -I ``` - 该命令会输出所有非回环接口的IP地址,以空格分隔。通常第一个是IPv4地址,后面可能是IPv6地址(如果有的话)[^1][^3]。 ### 方法2:使用 `ip` 命令(精确提取) ```bash # 获取IPv4地址(排除环回接口) ip -4 addr show | grep -v "lo:" | awk '/inet/ {print $2}' | cut -d'/' -f1 # 解释: # ip -4 addr show: 显示所有IPv4地址 # grep -v "lo:": 排除环回接口 # awk '/inet/ {print $2}': 匹配包含inet的行,并打印第二列(即IP地址/掩码位) # cut -d'/' -f1: 去掉掩码部分,只保留IP ``` ### 方法3:使用 `ifconfig` 命令 ```bash ifconfig | grep -v "lo" | grep "inet" | awk '{print $2}' | grep -v "addr:" | sort -u # 或者 ifconfig | grep -v "lo" | grep "inet" | awk '{print $2}' | sed 's/addr://g' ``` ### 方法4:使用C程序(如引用[3]所示) 引用[3]中的代码已经排除了环回接口(lo),所以可以直接使用。 ### 方法5:使用Python(无需安装额外包) 如果不希望安装`netifaces`,可以使用标准库(但可能复杂一些): ```python import socket import os def get_ip(): # 获取主机名 hostname = socket.gethostname() # 尝试获取所有IP地址 ip_list = socket.gethostbyname_ex(hostname)[2] # 过滤环回地址(127.0.0.1) ip_list = [ip for ip in ip_list if not ip.startswith('127.')] # 如果过滤后为空,则尝试其他方法 if not ip_list: # 这里可以尝试连接一个外部地址然后获取本地地址 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # 使用一个公共DNS地址(8.8.8.8)和任意端口(80) s.connect(("8.8.8.8", 80)) ip = s.getsockname()[0] ip_list.append(ip) except Exception: pass finally: s.close() return ip_list if __name__ == "__main__": ips = get_ip() for ip in ips: print(ip) ``` 以上方法中,最推荐在命令行中使用`hostname -I`,因为它简单、直接,并且通常已经预装在系统中。在脚本编程中,可以根据需要选择命令行工具或编程语言的方法。 §§相关问题§§ 1. 如何只获取公网IP地址而不包括私有IP地址? 2. 在Linux中如何获取MAC地址? 3. 如何判断一个IP地址是公网地址还是私有地址? </think>### Linux 系统获取 IP 地址并排除环回地址的方法 以下是几种可靠的方法,均能有效排除 `127.0.0.1`(IPv4)和 `::1`(IPv6)等环回地址: --- #### **方法 1:使用 `hostname` 命令(推荐)** ```bash hostname -I ``` - **输出示例**: `192.168.1.105 2001:db8::a60f:8dff:fe32:7d65` - **特点**: - 自动排除环回地址 - 同时显示所有接口的 IPv4/IPv6 地址 - 兼容大多数 Linux 发行版[^1] --- #### **方法 2:使用 `ip` 命令(精确控制)** ```bash # 获取 IPv4 地址(排除环回) ip -4 addr show | grep -v "lo" | grep -oP '(?<=inet\s)\d+(\.\d+){3}' # 获取 IPv6 地址(排除环回) ip -6 addr show | grep -v "lo" | grep -oP '(?<=inet6\s)[\da-f:]+' ``` - **关键参数**: - `-4`/`-6`:指定 IP 类型 - `grep -v "lo"`:排除环回接口 `lo` - `grep -oP`:正则精准提取地址 --- #### **方法 3:使用 `ifconfig` 命令(传统方式)** ```bash ifconfig | grep -v "127.0.0.1" | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' ``` - **注意**:需先安装 `net-tools` 包(`sudo apt install net-tools`) --- #### **方法 4:C 语言程序(系统级获取)** ```c #include <stdio.h> #include <ifaddrs.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { struct ifaddrs *addrs; getifaddrs(&addrs); while (addrs) { if (addrs->ifa_addr && addrs->ifa_addr->sa_family == AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)addrs->ifa_addr; // 排除环回地址和 lo 接口 if (strcmp(inet_ntoa(sa->sin_addr), "127.0.0.1") != 0 && strcmp(addrs->ifa_name, "lo") != 0) { printf("Interface %s: %s\n", addrs->ifa_name, inet_ntoa(sa->sin_addr)); } } addrs = addrs->ifa_next; } freeifaddrs(addrs); return 0; } ``` - **编译运行**: `gcc getip.c -o getip && ./getip`[^3] --- #### **方法 5:Python 脚本(跨平台)** ```python import socket import netifaces for interface in netifaces.interfaces(): # 排除环回接口 lo if interface == 'lo': continue addrs = netifaces.ifaddresses(interface) if netifaces.AF_INET in addrs: for addr_info in addrs[netifaces.AF_INET]: ip = addr_info['addr'] # 排除 127.0.0.1 if ip != '127.0.0.1': print(f"{interface}: {ip}") ``` - **依赖**:需安装 `netifaces` 库(`pip install netifaces`) --- ### **方法对比** | **方法** | **优势** | **适用场景** | |----------------|-----------------------------------|--------------------------| | `hostname -I` | 单命令完成,无需过滤 | 快速查看所有地址 | | `ip` 命令 | 精确控制输出,支持复杂过滤 | 脚本处理 | | C/Python 程序 | 可定制逻辑,适合嵌入到工具中 | 开发应用程序 | | `ifconfig` | 兼容旧系统 | 传统环境 | > **建议**:日常使用首选 `hostname -I`,脚本开发推荐 `ip` 命令或编程实现[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值