Skip to content

05 学以致用 - 日常工作中的 bash 脚本 -2

批量检测主机开机状态

bash
#!/bin/bash

# 检查是否提供了 IP 前缀参数
if [ -z "$1" ]; then
    echo "Usage: $0 <IP_PREFIX>"
    echo "Example: $0 192.168.1."
    exit 1
fi

# 获取用户输入的 IP 前缀
IP_PREFIX=$1

# 批量检测主机开机状态
for i in {1..6}; do

    # 以 0.3s 为间隔,以 1s 为超时时间,ping 相应的 IP 地址两次
    # ping -c [次数] -i [间隔] -W [超时时间] [IP]
    # ping 成功时,$? 返回值为 0,否则为 1。
    ping -c 2 -i 0.3 -W 1 ${IP_PREFIX}$i &>/dev/null

    # 判断 ping 的结果
    if [ $? -eq 0 ]; then # ping 通
        echo "${IP_PREFIX}$i is up"
    else # ping 不通
        echo "${IP_PREFIX}$i is down"
    fi
done
  • &>/dev/null:这个部分用于将 ping 的输出(包括标准输出和标准错误)重定向到 /dev/null,也就是不显示任何输出。

  • $? 是一个特殊变量,它存储上一条命令的退出状态码。对于 ping 命令来说:

    • 如果 ping 成功(主机在线,收到 ICMP 响应包),$? 返回 0。
    • 如果 ping 失败(主机不在线或没有响应),$? 返回 1。

    这里的 if [ $? -eq 0 ] 用于判断 ping 是否成功。

bash
  0904 git:(main) bash check_hosts_status.sh
Usage: check_hosts_status.sh <IP_PREFIX>
Example: check_hosts_status.sh 192.168.1.
  0904 git:(main) bash check_hosts_status.sh 10.0.16.
10.0.16.1 is down
10.0.16.2 is down
10.0.16.3 is up
10.0.16.4 is down
10.0.16.5 is down
10.0.16.6 is down

检测网卡流量并记录

bash
#!/bin/bash

# 检测网卡流量,并按规定格式记录在日志中
while true; do
    # 定义日志文件路径,文件名格式为日期.log
    logfile=/tmp/$(date +%Y%m%d).log

    # 将当前时间写入日志文件
    date +"%F %H:%M" >>$logfile

    # 使用 sar 命令统计 eth0 的网络流量,单位转换为 bps (bit/s)
    # sar 输出单位为 kb/s,转换为 bps 需要 * 1000 * 8
    sar -n DEV 1 2 | grep Average | grep eth0 | awk '{print $2,"\t","input:","\t",$5*1000*8,"bps\n\b",$2,"\t","output:","\t",$6*1000*8,"bps"}' >>$logfile

    # 输出分割线
    echo "########################" >>$logfile

    # 每隔 1 秒执行一次
    sleep 1
done

定义日志文件路径

bash
logfile=/tmp/$(date +%Y%m%d).log
  • 使用 date +%Y%m%d 命令动态生成一个包含当前日期的文件名(例如:20241004.log)。
  • logfile 的路径设置为 /tmp/,文件名为当天的日期,确保每天的日志都会保存在一个单独的文件中。

写入当前时间

bash
date +"%F %H:%M" >>$logfile
  • 使用 date 命令以 YYYY-MM-DD HH:MM 的格式将当前时间写入日志文件中。(%F 表示完整的日期,%H:%M 表示小时和分钟。例如:2024-10-04 14:32

统计网络流量

bash
  0904 git:(main) sar -n DEV 1 2 # 每秒采样一次,共采样两次
Linux 5.14.0-467.el9.x86_64 (VM-16-3-centos)    10/04/2024      _x86_64_        (4 CPU)

12:48:07 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
12:48:08 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:48:08 PM      eth0     13.00     17.00      0.91      4.04      0.00      0.00      0.00      0.00

12:48:08 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
12:48:09 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:48:09 PM      eth0     91.00     25.00    123.17      2.08      0.00      0.00      0.00      0.00

Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
Average:           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:         eth0     52.00     21.00     62.04      3.06      0.00      0.00      0.00      0.00

  0904 git:(main) sar -n DEV 1 2 | grep Average # 过滤出 Average 行
Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
Average:           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:         eth0     21.50     28.00      1.72      5.17      0.00      0.00      0.00      0.00

  0904 git:(main) sar -n DEV 1 2 | grep Average | grep 'eth0' # 继续过滤出 eth0 接口的流量信息
Average:         eth0      5.50      9.50      0.33      1.00      0.00      0.00      0.00      0.00

  0904 git:(main) sar -n DEV 1 2 | awk '/Average/ && /eth0/' # 或者使用 awk 命令过滤出 Average 行和 eth0 接口的流量信息
Average:         eth0      9.50     15.50      0.79      2.68      0.00      0.00      0.00      0.00

  0904 git:(main) sar -n DEV 1 2 | grep Average | grep 'eth0' | awk '{ print $2, $5, $6 }' # 打印 eth0 接口的流量信息
eth0 1.77 4.77
  0904 git:(main) sar -n DEV 1 2 | grep Average | grep 'eth0' | awk '{ print $2, $5*1000*8, $6*1000*8 }' # 将流量信息转换为 bps
eth0 14320 27120
  0904 git:(main) sar -n DEV 1 2 | grep Average | grep eth0 | awk '{print $2,"\t","input:","\t",$5*1000*8,"bps\n\b",$2,"\t","output:","\t",$6*1000*8,"bps"}'
eth0     input:          3200 bps
eth0     output:         25680 bps

  0904 git:(main) sar -n DEV 1 2 | awk '/Average/ && /eth0/ {print $2,"\t","input:","\t",$5*1000*8,"bps\n\b",$2,"\t","output:","\t",$6*1000*8,"bps"}'
eth0     input:          3360 bps
eth0     output:         11440 bps
  • sar -n DEV 1 2sar 是一个系统活动报告工具,用于采集网卡的流量数据。-n DEV 表示统计网络接口数据,1 2 表示每秒采样一次,共采样两次。

  • grep Average:过滤出 Average 行(包含了采样的结果)。

  • grep eth0:继续过滤出 eth0 接口的流量信息。如果你想监控其他接口(如 wlan0),可以替换 eth0wlan0

  • awk '/Average/ && /eth0/':使用 awk 命令过滤出 Average 行和 eth0 接口的流量信息。

  • awk '{print $2,"\t","input:","\t",$5*1000*8,"bps\n\b",$2,"\t","output:","\t",$6*1000*8,"bps"}':使用 awk 格式化输出数据。

    • $5$6 分别表示接收和发送的流量,以 kb/s(千比特每秒)为单位。我们将其乘以 1000 * 8 将单位转换为 bps(比特每秒)。

    • 输出格式为:

      bash
      eth0     input:     接收流量 bps
      eth0     output:    发送流量 bps

实验代码

bash
  0904 git:(main) bash monitor_network_traffic.sh & # 后台运行脚本
[1] 1857121

  0904 git:(main) jobs # 查看后台运行的进程
[1]  + running    bash monitor_network_traffic.sh
  0904 git:(main) wget "https://speed.cloudflare.com/__down?during=download&bytes=1073741824"
--2024-10-04 13:06:28--  https://speed.cloudflare.com/__down?during=download&bytes=1073741824
Resolving speed.cloudflare.com (speed.cloudflare.com)... 162.159.140.220, 172.66.0.218, 2a06:98c1:58::da, ...
Connecting to speed.cloudflare.com (speed.cloudflare.com)|162.159.140.220|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/octet-stream]
Saving to: ‘__down?during=download&bytes=1073741824’

73741824                      [                        <=>          ]  24.86M  1.57MB/s               ^C
  0904 git:(main)   tail /tmp/20241004.log # 查看日志文件
########################
2024-10-04 13:07
eth0     input:          7760 bps
eth0     output:         14160 bps
########################
2024-10-04 13:07
eth0     input:          4400 bps
eth0     output:         27680 bps
########################
2024-10-04 13:07
  0904 git:(main) jobs # 查看后台运行的进程
[1]  + running    bash monitor_network_traffic.sh
  0904 git:(main) kill %1 # 终止后台运行的进程
[1]  + 1857121 terminated  bash monitor_network_traffic.sh