在init.d脚本中使用Python的特殊注意事项?

在init.d脚本中使用Python的特殊注意事项?

问题描述:

在通过init运行的'init.d'脚本中使用Python有什么特别的注意事项吗? (即启动Ubuntu)在init.d脚本中使用Python的特殊注意事项?

根据我的理解,通过在Ubuntu上进行搜索/测试,提供给'init.d'脚本的环境变量很少,因此使用"#!/usr/bin/env python"可能无效。

还有其他吗?

这只是强调了python在init.d脚本中最大的问题 - 增加了复杂性。

Python没有规范,env甚至不必指向cpython。如果你升级和python休息,你必须咬舌头。 python会比sh(init.d脚本的安全赌注)更有可能发生断裂。原因是,简单实用:

 
[email protected]:/etc/init.d$ ldd /usr/bin/python 
    linux-gate.so.1 => (0xb7ff7000) 
    libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7fc9000) 
    libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7fc5000) 
    libutil.so.1 => /lib/tls/i686/cmov/libutil.so.1 (0xb7fc0000) 
    libz.so.1 => /lib/libz.so.1 (0xb7faa000) 
    libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7f84000) 
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e21000) 
    /lib/ld-linux.so.2 (0xb7ff8000) 
[email protected]:/etc/init.d$ ldd /bin/sh 
    linux-gate.so.1 => (0xb803f000) 
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7ec7000) 
    /lib/ld-linux.so.2 (0xb8040000) 

Python是链接到的libpthread,libdl中,libutil,libz进行,libm中除其他事项外,可不可能破碎。 Python只是做更多。

 
-rwxr-xr-x 1 root root 86K 2008-11-05 01:51 /bin/dash 
-rwxr-xr-x 1 root root 2.2M 2009-04-18 21:53 /usr/bin/python2.6 

你可以阅读更多的什么你特别谈论与ENV变量在这里: http://www.debian.org/doc/debian-policy/ch-opersys.html#s9.9 的主要问题是,ENV的默认设置可以在/ etc/profile文件这将只运行如果设置该脚本正在支持阅读的shell下运行。

我假设这是运行某种用python编写的守护进程,如果没有,那么这可能不适用。

你会(可能)想要做标准的unix双叉和重定向文件描述符的东西。这是我使用的一个(从ActiveState代码recepie改编,目前我的网址没有这个代码)。

def daemonize(stdin, stdout, stderr, pidfile): 
    if os.path.isfile(pidfile): 
     p = open(pidfile, "r") 
     oldpid = p.read().strip() 
     p.close() 
     if os.path.isdir("/proc/%s"%oldpid): 
      log.err("Server already running with pid %s"%oldpid) 
      sys.exit(1) 
    try: 
     pid = os.fork() 
     if pid > 0: 
      sys.exit(0) 
    except OSError, e: 
     log.err("Fork #1 failed: (%d) %s"%(e.errno, e.strerror)) 
     sys.exit(1) 
    os.chdir("/") 
    os.umask(0) 
    os.setsid() 
    try: 
     pid = os.fork() 
     if pid > 0: 
      if os.getuid() == 0: 
       pidfile = open(pidfile, "w+") 
       pidfile.write(str(pid)) 
       pidfile.close() 
      sys.exit(0) 
    except OSError, e: 
     log.err("Fork #2 failed: (%d) %s"%(e.errno, e.strerror)) 
     sys.exit(1) 
    try: 
     os.setgid(grp.getgrnam("nogroup").gr_gid) 
    except KeyError, e: 
     log.err("Failed to get GID: %s"%e) 
     sys.exit(1) 
    except OSError, e: 
     log.err("Failed to set GID: (%s) %s"%(e.errno, e.strerror)) 
     sys.exit(1) 
    try: 
     os.setuid(pwd.getpwnam("oracle").pw_uid) 
    except KeyError, e: 
     log.err("Failed to get UID: %s"%e) 
     sys.exit(1) 
    except OSError, e: 
     log.err("Failed to set UID: (%s) %s"%(e.errno, e.strerror)) 
     sys.exit(1) 
    for f in sys.stdout, sys.stderr: 
     f.flush() 
    si = open(stdin, "r") 
    so = open(stdout, "a+") 
    se = open(stderr, "a+", 0) 
    os.dup2(si.fileno(), sys.stdin.fileno()) 
    os.dup2(so.fileno(), sys.stdout.fileno()) 
    os.dup2(se.fileno(), sys.stderr.fileno()) 

在启动守护进程循环之前运行这个程序,它可能会做正确的事情。

作为一个方面说明,我使用#!/ usr/bin/env python作为脚本中的shebang行,它对于我来说工作正常。

即使您没有运行守护程序来提供调试信息,您仍可能仍希望将stdout/stderr重定向到文件。

+0

init脚本不是守护进程。 – 2009-09-10 14:35:53

+0

Peter - 我指的是/etc/init.d/目录中的脚本(在引导时执行);该脚本是用Python编写的(因为我受不了bash)。 – jldupont 2009-09-10 14:39:25