Особые соображения в отношении использования Python в init.d сценарии?

Едва ли полезный ответ, но только указать, которые 'определяют', не работает, как отвечено Топором (не вписался в комментарий):

VERSION=4.3.1
PACKAGE_NAME=foobar
DOWNLOAD_URL=www.foobar.com

define ANNOUNCE_BODY
    Version $(VERSION) of $(PACKAGE_NAME) has been released
    It can be downloaded from $(DOWNLOAD_URL)
    etc, etc
endef

all:
    @echo $(ANNOUNCE_BODY)

Это дает ошибку, которой не может быть найдена команда 'It', таким образом, это пытается интерпретировать вторую строку, ОБЪЯВЛЯЮТ О ТЕЛЕ как о команде.

9
задан SilentGhost 10 September 2009 в 04:32
поделиться

2 ответа

Это только подчеркивает самую большую проблему python в сценарии init.d - дополнительную сложность.

Python не имеет спецификации, и env даже не обязательно указывает на cpython. Если вы обновитесь и питон сломается, вам придется прикусить язык. И вероятность того, что python сломается, намного выше, чем sh (безопасный вариант для сценариев init.d). Причина в том, что простая утилита:

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

4
ответ дан 3 November 2019 в 07:14
поделиться

Я предполагаю, что это запускает какой-то демон, написанный на 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 в файл, даже если вы не запущен демон для предоставления отладочной информации.

1
ответ дан 3 November 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: