Chinaunix

标题: perl system怎么捕获ctrl+z? [打印本页]

作者: chgan100    时间: 2012-03-29 12:22
标题: perl system怎么捕获ctrl+z?
在perl里面,我用system调用了一个命令,但是用户在这个命令的执行过程中会有ctrl+z这种行为来想退出程序,怎么在perl脚本中来捕获和处理这种行为?
作者: sjdy521    时间: 2012-03-29 13:27
ctrl+z不是退出程序吧
作者: bikong0411    时间: 2012-03-29 14:43
$SIG{"SIGTSTP "}好像也不行
作者: Cu_fans    时间: 2012-03-29 18:50
$SIG{INT}

试下捕捉这个信号
作者: chgan100    时间: 2012-03-30 13:52
回复 3# bikong0411


    在perl这个主进程里面捕获$SIG{"SIGTSTP "}和 $SIG{"INT"}是可以处理主进程中的ctrl+z和ctrl+c的。
   但是在system这个命令实际上是重新创建了一个进程,所以在主进程里捕获子进程里的信号实际上是没有起作用的。
作者: chgan100    时间: 2012-03-30 13:53
回复 4# Cu_fans

在perl这个主进程里面捕获$SIG{"SIGTSTP "}和 $SIG{"INT"}是可以处理主进程中的ctrl+z和ctrl+c的。
   但是在system这个命令实际上是重新创建了一个进程,所以在主进程里捕获子进程里的信号实际上是没有起作用的。
   
作者: sjdy521    时间: 2012-03-30 14:04
本帖最后由 sjdy521 于 2012-03-30 14:04 编辑

回复 6# chgan100


    主进程,子进程都是属于一个进程组的
    一个信号整个进程组都应该是可以捕获到的

另外看楼主的意思,也是在主进程中捕获终端的信号,而不是捕获子进程的信号啊。
作者: chgan100    时间: 2012-03-30 14:26
回复 7# sjdy521


    我有写写过一个程序是:在等待用于输入的过程中,输入y继续,输入n退出,但是很多用户就不看提示,强制用ctrl+c或者ctrl+z或者有的更干脆用关掉ssh这种方式来退出,在这种情况下我捕获了$SIG{"SIGTSTP "}和 $SIG{"INT"}这两个信号是成功了。

  但是在另外一种情况是:主进程运行过程中,我用system调用了另外一个perl命令,在这个perl命令还在运行过程中用户使用ctrl+z想停止这个perl命令的运行并且退出整个程序。这种情况下在主进程里捕获$SIG{"SIGTSTP "}信号没有捕获成功。

举例说明:
下面这种情况是成功了:如果有ctrl+c或者ctrl+z行为就会调用errorsub函数。
###处理循环输入
sub cycinput
{
print RED,"\n\n\n*********************************************************************************\n",RESET;
print RED,"**如果要继续修改配置文件请输入Y或者y,如果不需要修改其他配置请输入n或N直接将改好的配置同步到服务器。\n",RESET;
print RED,"**如果没有输入n或N的话就重启服务则配置不会在服务器端生效,请注意!\n",RESET;
print RED,"**如果需要退出请输入q或Q,这个时候修改的配置会在部署平台生效,但是并没有同步到服务器\n",RESET;
print RED,"**如果要重启系统,请运行命令tremotecmd重启,谢谢。\n",RESET;
$SIG{TERM}=$SIG{INT}=$SIG{TSTP}=\&errorsub;
chomp($iscontinue=<STDIN>);

下面这种情况是不成功的:如果有ctrl+c或者ctrl+z行为就会直接退出
$iserr=system("export DEPLOY_PASSWORD=xxxx;/wls/bankdplysys/tools/deploytool dremotecmd -s $system -a $action |tee /home/banktest/logs/toperate.log/$system/$tremotecmdlog");
$SIG{TERM}=$SIG{INT}=$SIG{TSTP}=$SIG{HUP}=\&errorsub;
作者: sjdy521    时间: 2012-03-30 14:32
回复 8# chgan100


    额,怎么感觉讨论的东西和这个帖子的主题越来越远了。。
你第二个例子里,直接system一个子进程去执行命令,而在这个子进程中你根本没做信号捕获处理呀,你只在主进程里做了捕获处理呀。
主进程被咔嚓了,子进程当然也会被干掉
作者: sjdy521    时间: 2012-03-30 14:36
回复 8# chgan100


    我觉得楼主本来的意思就是怎么在主程序里捕获ctrl+z终止掉主进程,顺便也把system的子进程也干掉,不是讨论怎么样单单只干掉system子进程里的命令呢
作者: x9x9    时间: 2012-03-30 14:46
楼主的想法用 system 可能实现不了。楼主也许可以看下 POE 。
作者: chgan100    时间: 2012-03-30 17:02
回复 10# sjdy521
可能没描述清楚。我的想法是ctrl+c或者ctrl+z掉system的进程,然后不让主程序直接退出而是转到我预定的函数去处理。
谢谢 sjdy521  这么热情的参与讨论。

   
作者: chgan100    时间: 2012-03-30 17:03
回复 11# x9x9


    不了解 POE ,我看看先。谢谢
作者: sjdy521    时间: 2012-03-30 17:11
本帖最后由 sjdy521 于 2012-03-30 17:13 编辑

回复 12# chgan100


    那看样子我理解简单了,不使用system,单独开个子进程,执行相关的命令,主进程捕获到ctrl+z,kill掉子进程,然后自己继续做其他处理
这样子不就ok了?
作者: sjdy521    时间: 2012-03-30 17:28
回复 1# chgan100


    晕了,讨论了半天,都不知道绕到哪去了 用一个$SIG{CHLD}就搞定了啊,笨死了。。。
  1. perl -e '$SIG{CHLD} = sub {print "catch ctrl+c\n"};system("ping www.baidu.com -c 10")'
复制代码

作者: chgan100    时间: 2012-03-30 17:41
回复 15# sjdy521
谢谢
我试一下。呵呵


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2