2009-09-10 2 views
9

Есть ли какие-либо особые соображения для использования Python в сценарии 'init.d', который проходит через init? (т. е. загрузка Ubuntu)Особые соображения для использования Python в скрипте init.d?

Из-за того, что я понимаю с помощью поиска/тестирования на Ubuntu, переменные окружения, предоставляемые сценарию 'init.d', недостаточны, поэтому использование "#!/usr/bin/env python" может не работать.

Что-нибудь еще?

ответ

4

Это просто подчеркивает самую большую проблему с 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 Основная проблема заключается в том, что по умолчанию для окр может быть установлен в/и т.д./профиль, который будет работать только если скрипт запускается под оболочкой, которая поддерживает ее чтение.

1

Я предполагаю, что на этом запущен какой-то демон, написанный на python, если нет, то это может не примениться.

Вы, вероятно, захотите сделать стандартную двойную вилку unix и перенаправить файловые дескрипторы. Это тот, который я использую (адаптирован из получателя кода ActiveState, чей URL-адрес ускользает от меня в данный момент).

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 в скрипте на ubuntu, и он отлично работает для меня.

Возможно, вы все же захотите перенаправить stdout/stderr в файл, даже если вы не используете демона для предоставления информации об отладке.

+0

скрипты инициализации не являются демонами. –

+0

Peter - Я имею в виду скрипт в каталоге /etc/init.d/ (выполняется во время загрузки); указанный сценарий написан на Python (потому что я не могу выдержать bash). – jldupont

Смежные вопросы