2009-09-10 7 views
9

¿Existen consideraciones especiales para usar Python en un script 'init.d' que se ejecuta a través del init? (es decir, arrancar Ubuntu)Consideraciones especiales para usar Python en el script init.d?

Por lo que entiendo a través de googlear/probar en Ubuntu, las variables de entorno proporcionadas a un script 'init.d' son escasas y entonces el uso de "#!/usr/bin/env python" podría no funcionar.

¿Algo más?

Respuesta

4

Eso simplemente resalta el mayor problema con python en una secuencia de comandos init.d: ​​complejidad añadida.

Python no tiene especificación, y el env ni siquiera tiene que apuntar a cpython. Si actualiza y rompe pitón, tendrá que morderse la lengua. Y hay una probabilidad mucho mayor de que Python se rompa que sh (la apuesta segura para los scripts de init.d). La razón de ser, sencilla utilidad:

 
[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 es la vinculación en libpthread, libdl, libutil, libz, libm entre otras cosas que posiblemente se puedan romper. Python simplemente está haciendo más.

 
-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 

Usted puede leer más acerca de lo que estás hablando específicamente con variables env aquí: http://www.debian.org/doc/debian-policy/ch-opersys.html#s9.9 El principal problema es que los valores predeterminados para env se puede ajustar en/etc/profile que sólo funcionaría si el script se está ejecutando bajo un shell que admite su lectura.

1

Supongo que esto está ejecutando algún tipo de daemon escrito en python, si no, esto puede no ser aplicable.

Probablemente querrá hacer la doble horquilla estándar de Unix y redirigir las descripciones de los archivos. Este es el que uso (Adaptado de un receptor de código ActiveState cuya url se me escapa en este momento).

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()) 

Simplemente ejecute esto antes de iniciar su bucle daemon y probablemente haga lo correcto.

Como nota al margen, estoy usando #!/Usr/bin/env python como la línea shebang en un script en ubuntu y está funcionando bien para mí.

Probablemente aún desee redirigir stdout/stderr a un archivo, incluso si no está ejecutando un daemon para proporcionar información de depuración.

+0

Los scripts de inicio no son daemons. –

+0

Peter: me refiero a un script en el directorio /etc/init.d/ (ejecutado en el momento del arranque); dicha secuencia de comandos está escrita en Python (porque no soporto bash). – jldupont

Cuestiones relacionadas