2009-09-10 25 views
9

init aracılığıyla çalıştırılan bir 'init.d' komut dosyasında Python kullanımı için herhangi bir özel husus var mı? (yani, Ubuntu önyükleme)Init.d komut dosyasında Python'u kullanmayla ilgili özel durumlar var mı?

Ubuntu'da googling/test yoluyla anladığım kadarıyla, 'init.d' komut dosyasına sağlanan ortam değişkenleri kıttır ve bu nedenle "#!/usr/bin/env python" kullanılması işe yaramayabilir.

Başka bir şey var mı?

cevap

4

Bu, init.d komut dosyası karmaşıklığı içinde python ile ilgili en büyük problemi vurgular.

Python'un bir özelliği yoktur ve env'nin cpython'a işaret etmesi bile gerekmez. Yükseltme ve python molaları varsa, dilinizi ısırmanız gerekir. Ve python'un sh'dan daha fazla şansı vardır (init.d betikleri için güvenli bahis). Sebep olarak, basit bir yardımcı programdır:

 
[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 başka libpthread evre içine bağlanıyor, libdl, libutil, libz, muhtemelen kırabilir diğer şeyler arasında libm. Python daha fazlasını yapıyor.

 
-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 

Sen hakkında daha fazla okuyabilir özel olarak burada env değişkenleri ile bahsettiğinizi: temel sorun env için varsayılan yalnızca aday olacağını/etc/profile ayarlanabilir olduğundan http://www.debian.org/doc/debian-policy/ch-opersys.html#s9.9 betik, okumayı destekleyen bir kabuk altında çalıştırılıyor.

1

Bunun python dilinde yazılmış bir tür artalanı çalıştırdığını varsayarak, bu geçerli olmayabilir.

Muhtemelen standart unix çift çatal ve yönlendirme dosya tanıtıcıları bir şey yapmak isteyeceksiniz. Kullandığım bu (url'si şu anda bana karşı olan bir ActiveState kod resminden uyarlanmıştır).

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

Sadece bu işlem döngüsünü başlatmadan önce çalıştırın ve muhtemelen doğru olanı yapacağız.

Bir yan not olarak, ubuntu'daki bir komut dosyasında shebang çizgisi olarak #!/Usr/bin/env python kullanıyorum ve benim için iyi çalışıyor.

Hata ayıklama bilgisi sağlamak için bir daemon çalıştırmıyor olsanız bile, muhtemelen stdout/stderr dosyasını bir dosyaya yeniden yönlendirmek isteyeceksiniz.

+0

init betikleri yazı değildir. –

+0

Peter - /etc/init.d/ dizinindeki (önyükleme sırasında çalıştırılan) bir betiğe atıfta bulunuyorum; Söz konusu betik Python'da yazılmıştır (çünkü bash'a dayanamıyorum). – jldupont

İlgili konular