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

时间:2016-01-06 06:58:40

标签: python linux perl devops nohup

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

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

就像:

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

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

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

所以有人知道,如果有任何时间限制从系统保持返回状态导致发送挂断信号?

在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')
....

doSshpexpect子例程:

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但是 执行python host-bringup.py setup仍然在远程主机中运行。

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

2 个答案:

答案 0 :(得分:2)

终端断开连接时发送SIGHUP。如果您想创建一个与终端无关的流程,请daemonize

请注意,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是启动它的程序。
  2. perl的SID是启动它的程序。
  3. 由于会话未发生变化,终端会在正常断开连接时将SIGHUP发送至perl

    也就是说,nohup会更改perl处理SIGHUP的方式,因为它会被忽略。

    $ perl -e'system "kill", "-HUP", "$$"; print "SIGHUP was ignored\n"'
    Hangup
    
    $ echo $?
    129
    
    $ nohup perl -e'system "kill", "-HUP", "$$"; print "SIGHUP was ignored\n"'
    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行为!

答案 1 :(得分:1)

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

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

有关血腥的详细信息,请参阅

perldoc perlipc