在Shell编程中,trap
命令用于注册一个或多个信号的处理程序,以便在接收到信号时执行指定的操作。它的语法如下:
trap [COMMAND] [SIGNALS]
其中,COMMAND
是在接收到触发的信号后要执行的命令或脚本。SIGNALS
是要捕获的一个或多个信号的名称。可以是信号名称(比如SIGINT
、SIGHUP
等),也可以是信号编号(比如2
、9
等)。
使用 trap
命令,可以对捕获到的信号做如下处理:
- 执行指定的命令或脚本,用于响应该信号。
- 忽略信号,即不采取任何处理。
- 恢复信号到默认处理行为。
下面是几个 trap
命令的使用示例:
- 捕获信号并执行命令:
trap "echo 'Signal trapped!'" SIGINT
上述命令将捕获 SIGINT
信号(通常是通过按下 Ctrl+C 触发),并执行 echo 'Signal trapped!'
命令。
- 捕获多个信号并执行同一命令:
trap "echo 'Signal trapped!'" SIGINT SIGTERM
上述命令将捕获 SIGINT
和 SIGTERM
信号,并执行同一个命令。
- 恢复信号到默认处理行为:
trap "trap - SIGINT" SIGTERM
上述命令将捕获 SIGTERM
信号,并将 SIGINT
停止捕获,并恢复其默认处理行为。
trap
命令在脚本中常用于捕获和处理关键信号,比如在脚本退出前执行清理操作、捕获中断信号等。它提供了一种机制来控制信号的处理,并允许在特定情况下采取自定义操作或回退到默认行为。
以下脚本演示了trap命令注册cleanup处理函数的例子,该脚本通过top命令将运行时传入的进程的内存情况保存在virt.log和res.log文件中。
当输入ctrl+c后,执行自定义的cleanup函数,函数中调用运行analyse_men.py脚本,将log文件中记录的消息生成为图片。
#!/bin/bash
pid=`pidof $1`
trap cleanup SIGINT
cleanup(){
echo "Received Ctrl+C signal, exiting..."
python analyse_mem.py
exit
}
while true; do
#
top_result=$(top -n 1 -b -p "$pid" | grep $1 | awk '{print $5, $6}')
# 提取VIRT和RES数据
virt=$(echo "$top_result" | awk '{print $1}')
res=$(echo "$top_result" | awk '{print $2}')
# 将数据写入到文件中
echo "$virt" >> virt.log
echo "$res" >> res.log
sleep 10 # 等待10秒再次执行命令
done
import matplotlib.pyplot as plt
with open('res.log', 'r') as res_file, open('virt.log', 'r') as virt_file:
res_data = [float(line.strip()) for line in res_file]
virt_data = [float(line.strip()) for line in virt_file]
# 生成x轴的时间数据(每10秒一个间隔)
time_data = [i * 10 for i in range(len(res_data))]
# 生成res.png
plt.plot(time_data, res_data)
plt.xlabel('Time (s)')
plt.ylabel('RES')
plt.title('RES Data')
plt.savefig('res.png')
plt.clf()
# 生成virt.png
plt.plot(time_data, virt_data)
plt.xlabel('Time (s)')
plt.ylabel('VIRT')
plt.title('VIRT Data')
plt.savefig('virt.png')
注:shell中运行python脚本的方式 python xxx.py