Shell脚本可通过trap捕获SIGINT、SIGTERM等信号实现优雅退出,执行清理、日志记录等操作;需避免在处理函数中调用易中断命令或引发递归,并注意子shell不继承trap。
Shell脚本中,通过捕获信号(如 SIGINT、SIGHUP、SIGTERM)可以避免进程被粗暴中断,实现资源清理、日志记录、状态保存等优雅退出逻辑。
脚本运行时可能收到的典型信号:
kill 命令发送的终止信号,用于请求正常退出trap 是 Shell 内置命令,用于定义信号到达时执行的回调动作。基本语法为:trap 'command' SIGNAL_NAME 或 trap 'command' SIGNAL_NUMBER
trap 'cleanup; exit 1' INT TERM QUIT
cleanup() { echo "释放锁文件"; rm -f /tmp/myapp.lock; }<br>trap cleanup INT TERM
信号处理看似简单,实际易出错:
curl 或 sleep),否则可能陷入不可中断状态kill -TERM $$),引发死循环(...))或管道中的命令不继承父 shell 的 trap,需显式传递或改用主流程控制set -e 运行,trap 不会自动取消该选项,建议在 cleanup 中明确处理错误路径以下脚本模拟一个长期运行任务,支持安全中断并清理:
#!/bin/bashlockfile="/tmp/myscript.lock"<p>cleanup() {echo "[$(date)] 正在退出:清理资源..." >> /var/log/myscript.logrm -f "$lockfile"echo "已释放锁,退出。" >&2}</p><p>trap cleanup INT TERM</p><h1>创建锁文件</h1><p>if [ -e "$lockfile" ]; thenecho "锁文件存在,退出。" >&2exit 1fitouch "$lockfile"</p><h1>主逻辑:每5秒打印一次,直到被信号中断</h1><p>while true; doecho "运行中... PID: $$"sleep 5done