linux下ping加时间戳

本文介绍了一种结合Ping命令和时间戳的方法,用于长期监测网络状况。通过使用shell命令组合,可以实现对指定地址的持续Ping操作,并在输出中加入时间戳,便于后续的数据分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1.  

ping 127.0.0.1 |awk '{print strftime(%H:%M:%S) "\t" $0}' 

strftime补充:
函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。
%a 星期几的简写
%A 星期几的全称
%b 月份的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的前两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年份,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从1到7,星期一为1)
%U 第年的第几周,把星期日作为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号
语法
strftime(format,timestamp)参数 描述
format 可选。规定如何返回结果。
timestamp 可选。时间戳,默认是当前本地的



awk补充:

awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。


print与printf补充:

print 中不能使用%s ,%d 或%c;print 自动换行,printf 没有自动换行


由于一些原因,比如需要检查网络之间是否存在掉包等问题,会长时间去ping一个地址,由于会输出大量的信息而且最好要有时间戳,因此我们可以使用简单的几个shell命令组合就可以实现:长时间ping一个地址,记录每次ping的时间戳,并输出到文本保存,另外我们还可以将这个动作放到后台去执行,以免登陆注销之后被中断。

首先是长时间ping,这个非常简单,使用参数-c即可:
[root@test ~]# ping 192.168.2.1 -c 10 
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.638 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.341 ms
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.291 ms
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.259 ms
64 bytes from 192.168.2.1: icmp_seq=5 ttl=64 time=0.338 ms
64 bytes from 192.168.2.1: icmp_seq=6 ttl=64 time=0.339 ms
64 bytes from 192.168.2.1: icmp_seq=7 ttl=64 time=0.243 ms
64 bytes from 192.168.2.1: icmp_seq=8 ttl=64 time=0.234 ms
64 bytes from 192.168.2.1: icmp_seq=9 ttl=64 time=0.333 ms
64 bytes from 192.168.2.1: icmp_seq=10 ttl=64 time=0.284 ms

--- 192.168.2.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9002ms
rtt min/avg/max/mdev = 0.234/0.330/0.638/0.109 ms
上面我们ping了10次,每次的时间1秒,因此比如你要ping连天那么就是60*60*24*2=172800。
接下来是加时间戳:
root@test ~]# ping 192.168.2.1 -c 10 | awk '{ print $0"\t" strftime("%H:%M:%S",systime()) } '
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.    10:30:21
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.436 ms    10:30:21
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.343 ms    10:30:22
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.368 ms    10:30:23
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.280 ms    10:30:24
64 bytes from 192.168.2.1: icmp_seq=5 ttl=64 time=0.308 ms    10:30:25
64 bytes from 192.168.2.1: icmp_seq=6 ttl=64 time=0.360 ms    10:30:26
64 bytes from 192.168.2.1: icmp_seq=7 ttl=64 time=0.319 ms    10:30:27
64 bytes from 192.168.2.1: icmp_seq=8 ttl=64 time=0.274 ms    10:30:28
64 bytes from 192.168.2.1: icmp_seq=9 ttl=64 time=0.360 ms    10:30:29
64 bytes from 192.168.2.1: icmp_seq=10 ttl=64 time=0.265 ms    10:30:30
    10:30:30
--- 192.168.2.1 ping statistics ---    10:30:30
10 packets transmitted, 10 received, 0% packet loss, time 9000ms    10:30:30
rtt min/avg/max/mdev = 0.265/0.331/0.436/0.052 ms    10:30:30
然后我们把信息输出到文本:
[root@test ~]# ping 192.168.2.1 -c 10 | awk '{ print $0"\t" strftime("%H:%M:%S",systime()) } '>ping.log
[root@test ~]# cat ping.log
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.    10:37:23
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.398 ms    10:37:23
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.288 ms    10:37:24
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.465 ms    10:37:25
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.310 ms    10:37:26
64 bytes from 192.168.2.1: icmp_seq=5 ttl=64 time=0.275 ms    10:37:27
64 bytes from 192.168.2.1: icmp_seq=6 ttl=64 time=0.247 ms    10:37:28
64 bytes from 192.168.2.1: icmp_seq=7 ttl=64 time=0.339 ms    10:37:29
64 bytes from 192.168.2.1: icmp_seq=8 ttl=64 time=0.270 ms    10:37:30
64 bytes from 192.168.2.1: icmp_seq=9 ttl=64 time=0.297 ms    10:37:31
64 bytes from 192.168.2.1: icmp_seq=10 ttl=64 time=0.289 ms    10:37:32
    10:37:32
--- 192.168.2.1 ping statistics ---    10:37:32
10 packets transmitted, 10 received, 0% packet loss, time 9000ms    10:37:32
rtt min/avg/max/mdev = 0.247/0.317/0.465/0.067 ms    10:37:32
最后,我们需要把任务放到后台去:
[root@test ~]# nohup ping 192.168.2.1 -c 10 | awk '{ print $0"\t" strftime("%H:%M:%S",systime()) } '>ping1.log &
[1] 2616
[root@test ~]# ls
anaconda-ks.cfg  check1.sh  Desktop  eygle.com  httpd  login  pass.conf  ping1.log  ping.log  test1.sh  test1.sh1
[root@test ~]# cat ping1.log 
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.    10:40:22
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.373 ms    10:40:22
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.343 ms    10:40:23
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.335 ms    10:40:24
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.299 ms    10:40:25
64 bytes from 192.168.2.1: icmp_seq=5 ttl=64 time=0.372 ms    10:40:26
64 bytes from 192.168.2.1: icmp_seq=6 ttl=64 time=0.236 ms    10:40:27
64 bytes from 192.168.2.1: icmp_seq=7 ttl=64 time=0.394 ms    10:40:28
64 bytes from 192.168.2.1: icmp_seq=8 ttl=64 time=0.317 ms    10:40:29
64 bytes from 192.168.2.1: icmp_seq=9 ttl=64 time=0.490 ms    10:40:30
64 bytes from 192.168.2.1: icmp_seq=10 ttl=64 time=1.65 ms    10:40:31
    10:40:31
--- 192.168.2.1 ping statistics ---    10:40:31
10 packets transmitted, 10 received, 0% packet loss, time 9001ms    10:40:31
rtt min/avg/max/mdev = 0.236/0.480/1.650/0.395 ms    10:40:31
<think>我们被要求创建一个ping命令,该命令在每次执行时记录时间戳、目标IP和MAC地址,并将这些信息写入文本文件。 注意:ping命令本身不记录MAC地址,因为MAC地址是二层信息,而ping工作在三层。要获取目标IP对应的MAC地址,我们需要额外的步骤(通常目标IP不在同一子网时,我们获取的是网关的MAC地址)。 我们可以编写一个脚本,在每次ping之前先获取目标IP对应的MAC地址(通过ARP),然后执行ping并记录时间戳、IP和MAC到日志文件。 步骤: 1. 获取目标IP(作为脚本参数)。 2. 解析目标IP的MAC地址(注意:如果目标不在同一子网,则获取网关的MAC地址)。 3. 执行ping命令,同时记录时间戳。 4. 将每次ping时间戳、目标IP和MAC地址写入日志文件。 但是,ping命令是持续运行的,我们可能希望每次ping都记录一行。因此,我们可以使用循环,每次ping一次(使用-c1),然后记录,并循环执行。 另一种方法是使用ping命令的D选项(时间戳)并配合其他工具,但这样无法直接记录MAC地址。 因此,我们选择编写一个shell脚本,循环执行以下步骤: - 获取当前时间戳 - 解析目标IP的MAC地址(使用arping或arp命令,但注意arp缓存可能没有该IP的MAC地址,所以需要先发送一个包) - 发送一个ping包(-c1) - 记录时间戳、目标IP、MAC地址到日志文件 但是,频繁解析MAC地址可能效率低,且目标IP的MAC地址通常不会改变,我们可以先获取一次并记录,或者每次获取。 考虑到MAC地址可能变化(比如DHCP重新分配),我们在每次ping之前都获取一次。 获取MAC地址的方法: 方法1:使用`arp -n`命令,但需要先确保目标IP在ARP缓存中。如果不在,我们可以先发送一个arping或者ping一个包来获取。 方法2:使用`arping -c1 target_ip`,然后解析输出,但这样会多发送一个ARP请求。 我们可以先检查ARP缓存中是否有该IP的记录,如果没有,则发送一个ping包(-c1)来触发ARP解析(注意:ping会先做ARP解析,然后才发送ICMP)。然后从ARP缓存中读取。 具体步骤: 1. 检查ARP缓存:`arp -n | grep '目标IP'` 2. 如果没有,则执行一次ping(-c1)来获取。 3. 再次检查ARP缓存,提取MAC地址。 注意:如果目标IP是网关或者不在同一子网,那么ARP缓存中存储的是网关的MAC地址。 脚本设计: 我们可以让脚本接受两个参数:目标IP和日志文件路径(可选,默认可以定义为一个文件)。 循环次数也可以设定(或者无限循环,直到用户中断)。 示例脚本框架: ```bash #!/bin/bash # 检查参数 if [ "$#" -lt 1 ]; then echo "Usage: $0 <target_ip> [log_file]" exit 1 fi TARGET_IP=$1 LOG_FILE=${2:-ping_log.txt} # 如果日志文件不存在,创建并写入标题行 if [ ! -f "$LOG_FILE" ]; then echo "Timestamp,Target_IP,MAC_Address" > "$LOG_FILE" fi # 无限循环,按Ctrl+C退出 while true; do # 获取当前时间戳 TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S") # 检查ARP缓存中是否有目标IP的条目 MAC_ADDR=$(arp -n | grep -w "$TARGET_IP" | awk '{print $3}') # 如果MAC_ADDR为空,则发送一个ping包来触发ARP解析 if [ -z "$MAC_ADDR" ]; then ping -c1 "$TARGET_IP" > /dev/null 2>&1 # 再次检查 MAC_ADDR=$(arp -n | grep -w "$TARGET_IP" | awk '{print $3}') # 如果还是空,标记为unknown if [ -z "$MAC_ADDR" ]; then MAC_ADDR="unknown" fi fi # 发送一个ping包,并捕获结果(我们只关心是否成功,但为了记录,我们可以记录时间戳和IP、MAC) # 注意:这里我们发送一个包,并等待回复。如果网络延迟大,可能影响循环间隔。 ping -c1 "$TARGET_IP" > /dev/null 2>&1 # 记录到日志文件 echo "$TIMESTAMP,$TARGET_IP,$MAC_ADDR" >> "$LOG_FILE" # 等待一段时间再进行下一次,比如1秒 sleep 1 done ``` 但是,这个脚本每次循环只ping一次,并记录一次。它会在日志文件中记录每次ping时间戳、目标IP和MAC地址。 注意:MAC地址在ARP缓存中可能不会频繁变化,所以我们可以考虑减少获取MAC地址的次数(比如每10次获取一次),但为了简单,每次循环都获取。 另外,如果目标IP是跨网段的,那么ARP缓存中存储的是网关的MAC地址,这是正确的,因为数据包是通过网关转发的。 改进:我们可以使用`ping -c1`来同时触发ARP解析和ICMP请求,然后记录。这样就不需要先单独触发ARP解析了(因为ping命令会自动完成ARP解析)。所以我们可以先发送ping,然后从ARP缓存中读取MAC地址。 修改后的循环体: ```bash while true; do TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S") # 先发送一个ping包,然后立即从ARP缓存中获取MAC地址 ping -c1 "$TARGET_IP" > /dev/null 2>&1 # 从ARP缓存中获取MAC地址 MAC_ADDR=$(arp -n | grep -w "$TARGET_IP" | awk '{print $3}') # 如果MAC_ADDR为空,标记为unknown if [ -z "$MAC_ADDR" ]; then MAC_ADDR="unknown" fi echo "$TIMESTAMP,$TARGET_IP,$MAC_ADDR" >> "$LOG_FILE" sleep 1 done ``` 这样更简洁,而且保证每次ping后立即获取ARP缓存中的MAC地址。 注意:arp命令的输出格式可能因系统而异,上述`awk '{print $3}'`适用于大多数Linux系统(输出中第三列为MAC地址)。但建议测试一下。 在Linux上,`arp -n`的输出示例: Address HWtype HWaddress Flags Mask Iface 192.168.1.1 ether aa:bb:cc:dd:ee:ff C eth0 所以第三列是HWaddress,即MAC地址。 但是,如果目标IP不在同一子网,那么`arp -n`可能看不到目标IP的条目,因为目标IP不在ARP解析的范围内(此时ARP解析的是网关的IP)。因此,我们需要获取网关的MAC地址。 如何判断目标IP是否在同一子网?我们可以根据本机的路由表。但为了简化,我们可以直接获取默认网关的IP和MAC地址,并认为目标IP的MAC地址就是网关的MAC地址(当目标IP不在同一子网时)。 但是,在脚本中判断子网比较复杂。我们可以这样处理:如果`arp -n`中没有目标IP的条目,那么我们就获取默认网关的MAC地址,并把它作为目标IP的MAC地址(因为发往目标IP的数据包实际上是通过网关转发的,所以记录网关的MAC地址也是合理的)。 修改: ```bash while true; do TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S") # 发送pingping -c1 "$TARGET_IP" > /dev/null 2>&1 # 尝试获取目标IP的MAC地址 MAC_ADDR=$(arp -n | grep -w "$TARGET_IP" | awk '{print $3}') if [ -z "$MAC_ADDR" ]; then # 如果目标IP不在同一子网,我们获取默认网关的MAC地址 GATEWAY_IP=$(ip route show default | awk '/default/ {print $3}') MAC_ADDR=$(arp -n | grep -w "$GATEWAY_IP" | awk '{print $3}') if [ -z "$MAC_ADDR" ]; then MAC_ADDR="unknown" fi fi echo "$TIMESTAMP,$TARGET_IP,$MAC_ADDR" >> "$LOG_FILE" sleep 1 done ``` 这样,即使目标IP不在同一子网,我们也能记录网关的MAC地址。 注意:`ip route show default` 获取默认网关,然后取第三列(即网关IP)。同样,这个命令的输出格式可能因系统而异,但通常第三列是网关IP。 示例输出:`default via 192.168.1.1 dev eth0`,所以第三列是网关IP。 最后,我们可以将脚本保存为`ping_logger.sh`,并赋予执行权限。 使用示例:`./ping_logger.sh 8.8.8.8 ping_log.txt` 这个脚本会每秒ping一次目标IP,并记录时间戳、目标IP和MAC地址(或网关MAC地址)到日志文件中。 注意:频繁的ping可能会对网络造成一定负担,请根据实际情况调整sleep的时间。 另外,如果目标IP不可达,ping会失败,但MAC地址可能仍然会被记录(因为ARP解析可能成功,因为网关可达)。 如果网关也不可达,那么MAC地址会标记为unknown。 这个脚本满足了用户的需求:记录时间戳、IP和MAC地址到文本文件。 但是,如果用户希望每次ping都记录,并且ping命令本身输出到屏幕,同时记录到文件,我们可以修改。但根据要求,我们只需要记录到文件。 另外,用户可能希望看到实时的ping结果,我们可以将ping的输出同时显示出来,但脚本中我们重定向到了/dev/null,所以不显示。我们可以去掉重定向,让ping输出到控制台,但同时记录信息到文件。 修改:去掉`> /dev/null 2>&1`,这样ping的输出会显示在终端,同时脚本在后台记录日志。 但注意,这样终端会显示ping的输出,而日志文件只记录我们自定义的信息(时间戳、IP、MAC)。如果用户希望将ping的输出也重定向到日志文件,那么需要额外处理。 根据需求,用户只要求记录时间戳、IP和MAC,所以我们只记录这些。 因此,我们提供上述脚本。 注意:这个脚本依赖于arp和ip命令,在大多数Linux系统上都是可用的。 最后,我们生成相关问题。</think>以下是实现带时间戳、IP和MAC地址记录的ping命令的完整方案: ### 解决方案 要实现每次执行ping命令时记录时间戳、目标IP和MAC地址,需要结合ping命令和ARP查询功能。以下是具体步骤: #### 1. 创建日志记录脚本 保存为`ping_logger.sh`: ```bash #!/bin/bash # 检查参数 if [ $# -lt 1 ]; then echo "Usage: $0 <target_ip> [log_file]" exit 1 fi TARGET_IP=$1 LOG_FILE=${2:-ping_log.txt} # 获取目标MAC地址(通过网关) get_mac() { # 获取网关IP GATEWAY_IP=$(ip route show | grep 'default via' | awk '{print $3}') # 如果目标IP在本地网络 if ip route get "$TARGET_IP" | grep -q 'src'; then # 直接查询目标IP的MAC arp -n "$TARGET_IP" | awk '/ether/{print $3}' else # 查询网关MAC arp -n "$GATEWAY_IP" | awk '/ether/{print $3}' fi } # 执行带日志的ping ping "$TARGET_IP" | while read line; do TIMESTAMP=$(date +"[%Y-%m-%d %H:%M:%S]") MAC_ADDR=$(get_mac) echo "$TIMESTAMP $line | MAC: ${MAC_ADDR:-unknown}" | tee -a "$LOG_FILE" done ``` #### 2. 赋予执行权限 ```bash chmod +x ping_logger.sh ``` #### 3. 使用示例 ```bash # 基本用法(默认日志到ping_log.txt) ./ping_logger.sh 8.8.8.8 # 指定日志文件 ./ping_logger.sh 192.168.1.1 custom_log.txt ``` ### 工作原理 1. **时间戳记录**:使用`date +"[%Y-%m-%d %H:%M:%S]"`生成精确时间戳 2. **MAC地址获取**: - 通过`ip route`判断目标是否在本地网络 - 本地目标直接查询ARP缓存 - 远程目标记录网关MAC地址[^1] 3. **实时记录**:使用管道将ping输出重定向到`while read`循环 4. **日志保存**:`tee -a`同时显示输出并追到日志文件 ### 日志文件示例 ``` [2023-10-05 14:30:22] PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. | MAC: aa:bb:cc:dd:ee:ff [2023-10-05 14:30:22] 64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=15.3 ms | MAC: aa:bb:cc:dd:ee:ff [2023-10-05 14:30:23] 64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=16.1 ms | MAC: aa:bb:cc:dd:ee:ff ``` ### 注意事项 1. MAC地址可能显示为`unknown`的情况: - ARP缓存未更新(新设备首次访问) - 目标IP不可达 - 需要先发送ARP请求:`ping -c1 $TARGET_IP >/dev/null` 2. 跨网络目标显示的是网关MAC而非最终目标MAC(因MAC只在本地网络有效)[^1] 3. 需要安装`iproute2`包(通常Linux系统默认包含)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值