Python脚本部分无法在RedHat 6.5的init.d /内执行,为什么?

我创build了一个名为rmClusterinit.d脚本,它应该在关机时执行一个简单的python脚本,该脚本使用botoclosures特定的服务器群集,位于/etc/init.d/rmCluster 755 perms写为:

 #!/bin/sh # # chkconfig: 0 1 1 # description: My service # # Author: Me # # ### BEGIN INIT INFO # Provides: rmCluster # Required-Start: # Required-Stop: # Default-Start: 0 # Default-Stop: 0 # Short-Description: My service # Description: My service ### END INIT INFO case $1 in start) python /usr/local/sbin/instanceStopper.py & touch /tmp/theScriptWorks ;; esac exit 0 

我还在/etc/rc0.d/S00rmCluster创build了一个指向上面的符号链接。 请注意,我正在触摸正在成功发生的/ tmp中的文件。

python脚本也有755个权限,写成:

 #!/usr/bin/env python import boto.ec2 import subprocess conn=boto.ec2.connect_to_region("us-west-2") reservations = conn.get_all_instances() cluster = [] inst_id = subprocess.Popen(["wget", "-q", "-O", "-", "http://169.254.169.254/latest/meta-data/instance-id"], stdout=subprocess.PIPE).communicate()[0] for res in reservations: for inst in res.instances: if inst_id in inst.tags["Name"] and "cloudformation" not in inst.tags: cluster.append( "%s" %(inst.id) ) conn.terminate_instances(cluster) 

请注意,python脚本在直接调用时工作得很好,而且在直接运行init.d脚本时也可以正常工作。 我也试图删除python脚本中的shebang,并在init.d调用中指定python的path,但它仍然不起作用。

我最初的是,也许python库不再可用在这个运行时期,所以脚本失败,但我不知道如何检查。 另外,我已经考虑过,也许它需要放在rc.x dirs的其他地方。 目前我已经设定在S00,这是唯一的S00。 Killall我搬到了S01,然后停下来搬到了S02; 这些是rc.0中唯一的三个“S”脚本/

我很感激帮助

解决scheme是来自@Jayan和@Kjetil Joergensen的回应。

init.d脚本的最终工作版本如下所示:

 #!/bin/bash # # chkconfig: 2345 99 1 # description: My service # # Author: me # # ### BEGIN INIT INFO # Provides: rmCluster # Required-Start: # Required-Stop: # Default-Start: 0 # Default-Stop: 0 # Short-Description: My service # Description: My service ### END INIT INFO case "$1" in start) touch /var/lock/subsys/rmCluster ;; stop) /usr/bin/python /usr/local/sbin/instanceStopper.py ;; esac exit 0 

主要变化是:

  1. 将“开始”部分移到“停止”部分
  2. 触摸“开始”部分中的locking文件
  3. 修改'chkconfig:'参数,使其以正常的服务启动,同时也被杀死,从而防止脚本尝试执行post-networkingclosures,正如@Kjetil Joergensen

注意: python脚本没有改变。

两个需要注意的地方是,它需要运行service start rmCluster ,以便在运行级别0和6期间closures服务。对于我来说这是可以接受的,因为它在云端configuration期间已经设置好了,所以将这个步骤添加到EC2中是微不足道的用户数据。 第二个是脚本在重新启动时执行,对于每个用例来说都可能并不理想。 我将不得不做进一步的调查,看看如何使这个脚本只有runlevel 0实际运行“停止”。

谢谢你们的帮助。

(几乎)所有你需要知道的是在/etc/rc.d/rc这是用于改变运行级别的shell脚本,它是相当可读的,因为它应该是很容易的。

它所做的简要描述是:

  • 它首先遍历每个/ etc / rc <runlevel> .d / K <num> <subsystem>脚本,通过查找/ var / lock / subsys /来检查它是否启动,如果它是
  • 然后检查/ etc / rc <runlevel> .d / S <num> <subsystem>脚本,通过检查/ var / lock / subsys / <subsystem>来检查脚本是否停止运行。

(处理/ var / lock / subsys可能有一些方便的function)

如果在这之前的一切都是真实的,你想要做的可能是:

  • 确保存在/ var / lock / subsys / <yourscriptname>
  • 运行级别0似乎是合适的(除非你也想包括重启,这是6),你会想运行它/etc/rc0.d/K<num <90> <yourscriptname>,networking在90 ,所以改变你的执行停止而不是开始。 你可能还可以“启动”你的脚本作为相关运行级别的一部分(3,5,1是单用户无networking,2,4是未使用的),只需在/ var / lock / subsys中留下适当的东西
  • 你明确地想要消除&符号,因为你的脚本会在它完成之前返回,这取决于它通过脚本的其余部分咀嚼的速度达到90,然后closuresnetworking,稍后它会得到最终戛然而止。 为了避免关机时间过长,您需要在脚本中执行相应的error handling/超时处理,而不是仅仅closures它,而让其余的机会尽可能多。

你为什么不尝试改变你的init脚本

chkconfig:2345 99 1

把你的代码从“开始”移动到“停止”,并有一个空的“开始”的情况下,然后在你的脚本放在/etc/init.d后执行chkconfig –add

注意:您可能必须删除您可能已经创build的任何软链接。

此外,请确保您的init脚本执行时加载了正确的“PATH”。 由于你的Python程序已经是一个可执行文件,可能你可以称之为

/ path / to / program&

代替

python / path / to / program&

同样在init文件的“开始”部分添加以下行:

触摸/ var / lock / subsys / program

这基本上创build一个锁文件,当机器重新启动| 停止,系统会在开始停止之前检查每个服务的状态。 如果系统发现服务没有运行(如果locking文件不存在),系统可能不运行“停止”程序