📜  Unix 中的信号和陷阱

📅  最后修改于: 2022-05-13 01:57:32.388000             🧑  作者: Mango

Unix 中的信号和陷阱

在这篇文章中,我们将讨论 Unix 中信号和陷阱的概述,并通过一个例子来理解它。最后将总结 Unix 中信号和陷阱的不同场景。让我们一一讨论。

概述 :

  • 信号是发送到程序以通知其发生重要事件的软件中断。用户对非法内存访问错误的请求就是发生的例子。某些信号,例如中断信号,表明用户已要求程序执行通常不属于程序控制流一部分的操作。
  • Trap 指定并激活将在 shell 接收到信号或其他异常情况时执行的处理程序。
  • 当 shell 获得信号 SIGNAL SPEC 时,它将读取并执行 ARG。如果 ARG 不存在(并且仅提供单个信号规范),或者如果 ARG 是破折号(“-”),则每个给定信号都将重置为其默认值。如果 ARG 是空字符串,shell 和它调用的命令将忽略每个 SIGNAL SPEC。
  • 如果您在应用程序运行时按下 Ctrl-C 或 Ctrl-,它将在信号出现时立即终止。有时您不希望应用程序在信号到达后立即停止。您可以选择忽略信号并继续运行,或者您可以在退出脚本之前进行某种类型的清理。 trap 命令让您可以调节程序对信号的响应方式。
  • 信号是一种异步通信,由一个数字组成,如果按下特定键或发生任何异常,则该数字可以从一个进程传递到另一个进程或从操作系统传递到进程。

例子 -
如果您编写了任何数量的 bash 代码,您几乎肯定会遇到过 trap 命令。 Trap 使您能够捕获信号并在它们发生时运行代码。信号是在特定事件发生时传送到您的脚本的异步通知。这些警报中的大多数是针对您希望永远不会发生的情况,例如不正确的内存访问或糟糕的系统调用。但是,您可能希望解决一两个事件。还有一些系统永远不会创建的额外“用户”事件,可用于向您的脚本发送信号。 Bash 还有一个名为“EXIT”的伪信号,它会在你的脚本终止时执行。

在Python的实现:

Python3
#GeeksforGeeks
trap itsatrap 1 2 3 7
  
#cleanup method
cleanup()
{
  echo "We got the signal to clean, beginning"
  rm -rf /tmp/temp_*.$$
  echo "Done! ... exiting now!."
  exit 1
}
# for loop
for i in *
do
  sed s/FOO/BAR/g $i > /tmp/temp_${i}.$$ && mv /tmp/temp_${i}.$$ $i
done


注意——
不要运行上面的脚本,因为它是一个陷阱!

典型的 Unix/Linux 活动:

  • 每个信号都与一个默认程序相关联。脚本或程序在收到信号时执行的操作称为默认的信号操作。
  • 可能的默认操作之一是:
  • 结束这个过程
  • 跳过信号
  • 核心内存转储 当它收到信号时,它会生成一个名为核心的文件,其中包含进程的内存映像。
  • 结束程序。
  • 继续该过程直到结束。

Unix 中信号和陷阱的不同场景:

  1. 如果有几个命令设置为陷阱,它们必须被引用包围。您还会注意到命令行 shell 会在执行 trap 命令时进行扫描,并在收到上述信号之一时再次扫描。
  2. 如果你忽略一个信号,所有额外的 shell 都会做同样的事情。但是,如果您指定在接收到信号时要执行的操作,则所有子外壳在接收到信号时仍将执行该操作。
  3. 有时您可能不希望脚本的用户通过使用键盘中止序列而过早退出,例如需要输入或需要清理时。 trap 语句拦截这些序列,并且可能被设计为在它们被拦截时执行一组命令。
  4. 当 Bash 在等待命令完成时接收到设置了陷阱的信号时,直到命令完成才会执行陷阱。
  5. 当 Bash 使用 wait 内置函数等待异步命令时,已设置陷阱的信号的到来会导致 wait 内置函数立即返回,退出状态大于 128,并执行陷阱.
  6. 当接收到一个或多个指定信号时,此命令定义要执行的操作。当外壳收到某个信号时,它会执行指示的操作。
  7. 指定要捕获的信号。您可以选择指定信号编号或信号名称。指定信号名称时,必须省略前导 SIG(例如,为 SIGINT 指定 INT)。每个信号的要求可以在所用操作系统的文档中找到。
  8. 需要注意的是,不能指定 SIGTERM。