在通過init
運行的'init.d'
腳本中使用Python有什麼特別的注意事項嗎? (即啓動Ubuntu)在init.d腳本中使用Python的特殊注意事項?
根據我的理解,通過在Ubuntu上進行搜索/測試,提供給'init.d'
腳本的環境變量很少,因此使用"#!/usr/bin/env 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重定向到文件。
init腳本不是守護進程。 – 2009-09-10 14:35:53
Peter - 我指的是/etc/init.d/目錄中的腳本(在引導時執行);該腳本是用Python編寫的(因爲我受不了bash)。 – jldupont 2009-09-10 14:39:25