我有一个简单的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
正如你所看到的,
perl
的PPID就是启动它的程序的PPIDperl
的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