在perl/python中保持系统退出状态的超时限制



我有一个简单的perl脚本,它调用另一个python脚本来在云中部署服务器。

我在perl中捕获部署的退出状态,以便在成功/失败设置后采取任何进一步的操作。

就像:

$cmdret = system("python script.py ARG1 ARG2");

在这里,python脚本运行3小时到7小时。

这里的问题是,无论成功或失败返回状态如何,即使过程在后台运行并进一步中断步骤,系统也会在该步骤随机接收信号HUP。

那么,有人知道吗,保持系统返回状态是否有时间限制,从而发送Hangup信号?

在python脚本script.py中,pexpect用于远程执行脚本:

doSsh(User,Passwd,Name,'cd '+OutputDir+';python host-bringup.py setup')
doSsh(User,Passwd,Name,'cd '+OpsHome+'/ops/hlevel;python  dshost.py start')
....

doSsh是一个pexpect子程序:

def doSsh(user,password,host,command):
    try:
        child =  pexpect.spawn("ssh  -o ServerAliveInterval=100 -n %s@%s '%s'" % (user,host,command),logfile=sys.stdout,timeout=None)
        i = child.expect(['password:', r'(yes/no)',r'.*password for paasusr: ',r'.*[$#] ',pexpect.EOF])
        if i == 0:
                child.sendline(password)
        elif i == 1:
                child.sendline("yes")
                child.expect("password:")
                child.sendline(password)
        data = child.read()
        print data
        child.close()
        return True
    except Exception as error:
        print error
        return False

第一次执行doSsh需要~6小时,此会话在执行数小时后终止,并显示消息:Signal HUP caught; exiting但是执行CCD_ 7仍然在远程主机中运行。

因此,在本地系统中,下一个doSsh永远不会运行,perl脚本中的其余步骤也永远不会继续。

SIGHUP在终端断开连接时发送。当你想创建一个不绑定到终端的进程时,你可以对它进行后台处理


请注意,nohup不会取消名字。

$ nohup perl -e'system "ps", "-o", "pid,ppid,sid,cmd"'
nohup: ignoring input and appending output to `nohup.out'
$ cat nohup.out
  PID  PPID   SID CMD
21300 21299 21300 -bash
21504 21300 21300 perl -esystem "ps", "-o", "pid,ppid,sid,cmd"
21505 21504 21300 ps -o pid,ppid,sid,cmd

正如你所看到的,

  1. perl的PPID就是启动它的程序的PPID
  2. perl的SID是启动它的程序的SID

由于会话没有改变,因此当正常断开连接时,终端将向perl发送SIGHUP。

也就是说,nohup通过使其被忽略来改变perl处理SIGHUP的方式。

$ perl -e'system "kill", "-HUP", "$$"; print "SIGHUP was ignoredn"'
Hangup
$ echo $?
129
$ nohup perl -e'system "kill", "-HUP", "$$"; print "SIGHUP was ignoredn"'
nohup: ignoring input and appending output to `nohup.out'
$ echo $?
0
$ tail -n 1 nohup.out
SIGHUP was ignored

如果perl被信号杀死,那是因为perl处理SIGHUP的方式发生了变化。

因此,要么守护进程,要么让perl忽略使用SIGHUP(例如,使用nohup)。但是,如果您使用nohup,请不要重新启用默认的SIGHUP行为!

如果您的目标是让perl程序忽略HUP信号,那么您可能只需要设置$SIG全局信号处理程序hash:的HUP条目

$SIG{ 'HUP' } = 'IGNORE';

欲知血腥细节,请参阅

perldoc perlipc

最新更新