Perl:是否可以撤消 SIG{INT} 捕获?

hel*_*d95 4 perl signals

我正在尝试在我的 Perl 程序中添加一个捕获信号。当 ctrl+C 发生时,我想要一条确认消息和一个用户输入( Y 或 N )。Y 输入工作正常。

如果用户输入 N,那么基本上我想“取消” ctrl+C 命令并返回到脚本。

编码:

$SIG{INT} = \&catchSignal;
$SIG{TERM} = \&catchSignal;

sub catchSignal
{
   my $ans;
   print " Are you sure you want to quit? Y or N:\n";
   $ans = <STDIN>;

   chomp $ans;

   if( $ans eq "Y" )
   {
      exit;
   }
   else
   {
      # Cancel the ctrl+C command
   }

}
Run Code Online (Sandbox Code Playgroud)

这样的事情可能吗?

zdi*_*dim 6

一旦您安装了处理程序,该信号的默认操作将被抑制,并且一旦该信号进入,您的处理程序就会运行。请参阅perlipc中的信号以了解初学者。

因此,您显示的内容已经“取消”了信号,并且您的程序将在处理程序返回后继续,除非用户当然确认退出。程序在哪里以及如何继续并不是一成不变的,但通常是在中断之后。

如果阻塞系统调用被信号中断,则该调用失败并显示EINTR( errno(3))。这些错误代码主要反映在%!variable 中,因此当这样的调用返回错误时,我们可以检查是否$!{EINTR}已设置,如果已设置,则重新启动该调用可能很有意义。感谢您ikegami发表评论。

确切地说,这是什么电话并没有明确规定,但可以从中推断出来signal(7)(参见脚注)。

如果他们确实选择退出,那比被信号吹出水面更好,因为具有停止程序的倾向的信号只会终止它。而当程序调用exit受控制并且可以清理时,使用选定的代码退出;此外,缓冲区被刷新,END块运行。


无法捕获的信号除外,首先是STOP(sigstop) 和KILL(sigkill)。

在C,我们可以设置SA_RESTARTsigaction(2) 有重新启动此类电话(见Interruption of system calls...signal(7)为例),但不与本机%SIG在Perl。有支持,POSIX::sigaction但它的使用相当复杂并且实际上没有记录。