Pregunta

¿Hay alguna consideración especial para usar Python en una secuencia de comandos 'init.d' que se ejecuta a través de init ? (es decir, arranque de Ubuntu)

Por lo que entiendo a través de googlear / testing en Ubuntu, las variables de entorno proporcionadas a un script 'init.d' son escasas y, por lo tanto, utilizan " #! / usr / bin / es posible que env python " no funcione.

¿Algo más?

¿Fue útil?

Solución

Eso solo resalta el problema más grande de python en un script init.d: ??complejidad agregada.

Python no tiene especificación, y el env ni siquiera tiene que apuntar a cpython. Si actualizas y rompes python, tendrás que morderte la lengua. Y hay una probabilidad mucho mayor de que Python se rompa que sh (la apuesta segura para los scripts init.d). La razón es, utilidad simple:

ecarroll@x60s:/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)
ecarroll@x60s:/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 se está vinculando a libpthread, libdl, libutil, libz, libm, entre otras cosas que posiblemente se pueden 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

Puede leer más sobre lo que está hablando específicamente con las variables env aquí: http://www.debian.org/doc/ debian-policy / ch-opersys.html # s9.9 El problema principal es que los valores predeterminados para env se pueden establecer en / etc / profile, que solo se ejecutaría si el script se ejecuta bajo un shell que admite su lectura.

Otros consejos

Supongo que esto está ejecutando algún tipo de demonio escrito en python, de lo contrario, es posible que esto no se aplique.

Usted (probablemente) querrá hacer la doble horquilla estándar de Unix y redirigir los descriptores de archivos. Este es el que yo uso (Adaptado de un archivo de código ActiveState cuya URL me elude 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 ejecuta esto antes de iniciar el bucle de tu daemon y probablemente hará 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í.

Es probable que aún desees redirigir stdout / stderr a un archivo, incluso si no estás ejecutando un demonio para proporcionar información de depuración.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top