运维面试必备:Shell 脚本中如何使用 trap 命令捕捉和处理信号
在 Unix/Linux 系统中,信号是进程间通信的一种机制,用于通知进程发生了某种事件。常见的信号包括:
·
Shell面试题 - Shell 脚本中如何使用trap命令捕捉和处理信号?
1. 信号概述
在 Unix/Linux 系统中,信号是进程间通信的一种机制,用于通知进程发生了某种事件。常见的信号包括:
| 信号编号 | 信号名称 | 说明 |
|---|---|---|
| 1 | SIGHUP | 终端挂断或控制进程终止 |
| 2 | SIGINT | 键盘中断 (Ctrl+C) |
| 3 | SIGQUIT | 键盘退出 (Ctrl+) |
| 9 | SIGKILL | 强制终止 |
| 15 | SIGTERM | 终止信号 |
2. trap 命令基本用法
trap 命令用于在 shell 脚本中捕获并处理信号,基本语法如下:
trap 'command' SIGNAL
示例 1:捕获 Ctrl+C (SIGINT)
#!/bin/bash
trap 'echo "You pressed Ctrl+C!"' SIGINT
echo "Press Ctrl+C to test"
sleep 10
echo "Done"
3. 常见的 trap 使用场景
3.1 清理临时文件
#!/bin/bash
tempfile=$(mktemp)
cleanup() {
echo "Removing temp file..."
rm -f "$tempfile"
exit
}
trap cleanup EXIT SIGINT SIGTERM
echo "Working with temp file: $tempfile"
# 模拟工作
sleep 10
3.2 忽略信号
#!/bin/bash
trap '' SIGINT # 忽略SIGINT信号
echo "Try pressing Ctrl+C, it won't work now"
sleep 5
echo "Done"
3.3 重置信号处理
#!/bin/bash
trap 'echo "First trap"' SIGINT
sleep 2 & wait
trap 'echo "Second trap"' SIGINT # 覆盖之前的处理
sleep 2 & wait
trap - SIGINT # 重置为默认行为
sleep 2 & wait
4. Java 中的信号处理
虽然本文主要讨论 shell 脚本中的信号处理,但这里提供一个 Java 中处理信号的示例作为对比:
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class SignalExample {
public static void main(String[] args) {
// 处理SIGINT (Ctrl+C)
Signal.handle(new Signal("INT"), new SignalHandler() {
public void handle(Signal sig) {
System.out.println("Received SIGINT (Ctrl+C)");
// 清理工作
System.exit(0);
}
});
System.out.println("Press Ctrl+C to test");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Done");
}
}
5. 高级用法
5.1 获取触发 trap 的信号
#!/bin/bash
handler() {
echo "Caught signal $1"
}
trap 'handler SIGINT' SIGINT
trap 'handler SIGTERM' SIGTERM
echo "PID: $$"
sleep 10
5.2 在函数中使用 trap
#!/bin/bash
setup() {
trap 'echo "Exit signal caught"; exit' EXIT
echo "Trap set in setup function"
}
setup
echo "Main script running"
sleep 2
6. 注意事项
SIGKILL和SIGSTOP不能被捕获、阻塞或忽略- trap 命令的作用范围是当前的 shell 进程
- 子进程默认不会继承父进程的信号处理方式
- 在函数中设置的 trap 会影响整个脚本
7. 总结
trap 命令是 shell 脚本中处理信号的强大工具,可以用于:
- 优雅地处理脚本中断
- 执行清理操作
- 忽略特定信号
- 自定义信号处理行为
合理使用 trap 可以使脚本更加健壮和可靠。
更多推荐




所有评论(0)