Domanda

Esistono considerazioni speciali sull'uso di Python in uno script 'init.d' che viene eseguito tramite init ? (es. avvio di Ubuntu)

Da quello che ho capito tramite google / test su Ubuntu, le variabili di ambiente fornite a uno script 'init.d' sono scarse e quindi usando " #! / usr / bin / env python " potrebbe non funzionare.

Qualcos'altro?

È stato utile?

Soluzione

Ciò evidenzia solo il problema più grande con Python in uno script init.d - ha aggiunto complessità.

Python non ha specifiche e l'env non deve nemmeno puntare a cpython. Se esegui l'upgrade e le pause di Python, dovrai morderti la lingua. E c'è una possibilità molto più grande che Python si rompa rispetto a sh (la scommessa sicura per gli script init.d). Essendo la ragione, semplice utility:

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 si sta collegando in libpthread, libdl, libutil, libz, libm tra le altre cose che possono eventualmente rompersi. Python sta semplicemente facendo di più.

-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

Puoi leggere di più su ciò di cui stai specificamente parlando con le variabili env qui: http://www.debian.org/doc/ debian-policy / ch-opersys.html # s9.9 Il problema principale è che i valori predefiniti per env possono essere impostati in / etc / profile che verrebbe eseguito solo se lo script viene eseguito in una shell che supporta la lettura.

Altri suggerimenti

Suppongo che stia eseguendo una specie di demone scritto in Python, altrimenti potrebbe non essere applicabile.

Probabilmente vorrai fare il doppio fork standard di Unix e reindirizzare i descrittori di file. Questo è quello che uso (adattato da una ricezione di codice ActiveState il cui url mi sfugge al 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())

Eseguilo prima di avviare il tuo daemon loop e probabilmente farà la cosa giusta.

Come nota a margine, sto usando #! / usr / bin / env python come linea shebang in uno script su Ubuntu e funziona bene per me.

Probabilmente vorrai comunque reindirizzare stdout / stderr su un file anche se non stai eseguendo un demone per fornire informazioni di debug.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top