跳转到主要内容

基于Unix系统的守护进程控制库和工具

项目描述

zdaemon 是一个Unix(Unix、Linux、Mac OS X)Python程序,它将命令包装起来以使它们表现为合适的守护进程。

使用zdaemon

zdaemon提供了一个名为zdaemon的脚本,可以用作运行其他程序作为POSIX(Unix)守护进程。(当然,它只能在符合POSIX的系统上使用。)

使用zdaemon需要指定一些选项,这些选项可以作为一个配置文件提供,或者作为命令行选项提供。它还接受命令,告诉它要做什么。命令有:

start

以守护进程方式启动进程

stop

停止正在运行的守护进程

restart

停止并重新启动程序

status

查看程序是否正在运行

foreground 或 fg

运行程序

kill signal

向守护进程发送信号

reopen_transcript

重新打开传输日志。请参阅下面对传输日志的讨论。

help command

获取命令的帮助

命令可以在命令行中给出,也可以使用交互式解释器给出。

让我们从一个简单的例子开始。我们将使用命令行选项来运行echo命令

sh> ./zdaemon -p ‘echo hello world’ fg echo hello world hello world

这里我们使用了-p选项来指定要运行的程序。我们可以在程序命令中指定程序名称和命令行选项。请注意,然而,命令行解析相当原始。引号和空格没有被正确处理。让我们看看一个稍微复杂一点的例子。我们将以守护进程的形式运行sleep命令 :)

sh> ./zdaemon -p ‘sleep 100’ start ... 守护进程启动,pid=819

这运行了sleep守护进程。我们可以使用status命令检查它是否运行

sh> ./zdaemon -p ‘sleep 100’ status 程序正在运行;pid=819

我们可以使用stop命令停止它

sh> ./zdaemon -p ‘sleep 100’ stop ... 守护进程停止

sh> ./zdaemon -p ‘sleep 100’ status 守护进程管理器未运行 失败:3

通常,我们通过配置文件来控制zdaemon。让我们创建一个典型的配置文件

<runner>
  program sleep 100
</runner>

现在,我们可以使用-C选项来读取配置文件运行

sh> ./zdaemon -Cconf start ... 守护进程启动,pid=1136

如果我们列出目录

sh> ls conf zdaemon zdsock

我们将看到创建了一个文件,zdsock。这是ZDaemon内部使用的Unix域套接字。我们通常想控制它的位置。

sh> ./zdaemon -Cconf stop ... 守护进程停止

以下是更新后的配置

<runner>
  program sleep 100
  socket-name /tmp/demo.zdsock
</runner>

现在,当我们运行zdaemon时

sh> ./zdaemon -Cconf start ... 守护进程启动,pid=1139

sh> ls conf zdaemon

套接字文件被创建在指定的目录中。

sh> ./zdaemon -Cconf stop ... 守护进程停止

在示例中,我们在程序选项中包含了命令行参数。我们也可以在命令行上提供选项

<runner>
  program sleep
  socket-name /tmp/demo.zdsock
</runner>

然后我们可以在命令行上传递程序参数

sh> ./zdaemon -Cconf start 100 ... 守护进程启动,pid=1149

sh> ./zdaemon -Cconf status 程序正在运行;pid=1149

sh> ./zdaemon -Cconf stop ... 守护进程停止

环境变量

有时,在运行程序之前设置环境变量是必要的。最常见的情况可能是设置LD_LIBRARY_PATH,以便可以找到动态加载的库。

<runner>
  program env
  socket-name /tmp/demo.zdsock
</runner>
<environment>
  LIBRARY_PATH /home/foo/lib
  HOME /home/foo
</environment>

现在,当我们运行命令时,我们将看到环境设置被反映出来

sh> ./zdaemon -Cconf fg env USER=jim HOME=/home/foo LOGNAME=jim USERNAME=jim TERM=dumb PATH=/home/jim/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin EMACS=t LANG=en_US.UTF-8 SHELL=/bin/bash EDITOR=emacs LIBRARY_PATH=/home/foo/lib

传输日志

当zdaemon以守护进程模式运行程序时,它会将程序的标准输入、标准输出和标准错误从控制终端断开。它可以选择将输出重定向到标准错误,将标准输出重定向到文件。这是通过transcript选项完成的。这对于记录长运行应用程序的输出当然很有用。

让我们看看一个例子。我们将有一个长时间运行的过程,它简单地将数据文件尾部跟随

>>> f = open('data', 'w', 1)
>>> import os
>>> _ = f.write('rec 1\n'); f.flush(); os.fsync(f.fileno())

现在,这是我们的zdaemon配置

<runner>
  program tail -f data
  transcript log
</runner>

现在我们将启动

sh> ./zdaemon -Cconf start ... 守护进程启动,pid=7963

等待一段时间后,如果我们查看日志文件,它将包含tail输出

>>> with open('log') as file:
...     file.read()
'rec 1\n'

我们可以通过重命名它并告诉zdaemon重新打开它来旋转transcript日志

>>> import os
>>> os.rename('log', 'log.1')

如果我们生成更多输出

>>> _ = f.write('rec 2\n'); f.flush(); os.fsync(f.fileno())

输出将出现在旧文件中,因为zdaemon仍然打开它

>>> with open('log.1') as file:
...     file.read()
'rec 1\nrec 2\n'

现在,如果我们告诉zdaemon重新打开文件

sh> ./zdaemon -Cconf reopen_transcript

并生成一些输出

>>> _ = f.write('rec 3\n'); f.flush(); os.fsync(f.fileno())

输出将出现在新文件中,而不是旧文件

>>> with open('log') as file:
...     file.read()
'rec 3\n'
>>> with open('log.1') as file:
...     file.read()
'rec 1\nrec 2\n'

关闭文件并清理

>>> f.close()

sh> ./zdaemon -Cconf stop ... 守护进程停止

启动测试程序和超时

通常,zdaemon认为进程启动时进程本身已被创建。进程可能需要一段时间才能真正运行起来。例如,数据库服务器或网络服务器可能需要一段时间才能准备好接受请求。

您可以可选地通过 start-test-program 配置选项提供测试程序,该程序会重复调用,直到返回 0 退出状态或达到时间限制 start-timeout

参考文档

以下选项可以在配置文件的运行器部分和命令行选项中使用。

程序

命令行选项:-p 或 –program

此选项提供了启动由 zdaemon 管理的子进程所使用的命令。目前这是一个简单的空格分隔的单词列表。第一个单词是程序文件,后续的单词是其命令行参数。如果程序文件不包含斜杠,它将使用 $PATH 进行搜索。(注意,无法在程序文件或参数中包含空格,并且在某些情况下,其他 shell 元字符也可能成为问题。)

套接字名称

命令行选项:-s 或 –socket-name。

Unix 域套接字的路径名,用于 zdaemon 命令行工具与守护进程管理进程之间的通信。默认情况下,相对于 zdaemon 启动的当前目录。您在这里需要指定绝对路径名。

默认为“zdsock”,在 zdrun 启动的目录中创建。

守护进程

命令行选项:-d 或 –daemon。

如果此选项为真,zdaemon 以真正的守护进程方式在后台运行。它派生一个子进程,成为子进程管理器,而父进程退出(使启动它的 shell 认为它已完成)。子进程还执行以下操作

  • 如果设置了目录选项,切换到该目录

  • 将 stdin、stdout 和 stderr 重定向到 /dev/null

  • 调用 setsid() 成为会话领导者

  • 使用指定的值调用 umask()

此选项默认开启。因此,命令行选项没有效果。要禁用守护进程模式,您必须使用配置文件

<runner>
  program sleep 1
  daemon off
</runner>
目录

命令行选项:-z 或 –directory。

如果守护进程选项为真(默认),则此选项可以指定 zdrun.py 在“守护进程化”过程中更改的目录。如果守护进程选项为假,则忽略此选项。

退避限制

命令行选项:-b 或 –backoff-limit。

当子进程崩溃时,zdaemon 在重新启动它之前插入一秒钟的延迟。当子进程立即再次崩溃时,延迟增加一秒,依此类推。当延迟达到退避限制(秒)的值时会发生什么,取决于永远选项的值。如果永远为假,zdaemon 在此点放弃,并退出。在这种情况下,崩溃的子进程将正好重新启动退避限制次数。如果永远为真,zdaemon 继续尝试重新启动进程,保持延迟为退避限制秒。

如果子进程持续运行超过退避限制秒,则延迟重置为 1 秒。

默认为 10。

永远

命令行选项:-f 或 –forever。

如果此选项为真,zdaemon 将无限期地重新启动崩溃的子进程。如果为假,它将在连续崩溃退避限制次后放弃。有关详细信息,请参阅退避限制的说明。

默认禁用。

退出代码

命令行选项:-x 或 –exit-codes。

默认为 0,2。

如果子进程以与列表中任意一个整数相同的退出状态退出,zdaemon将不会重新启动它。默认列表需要一些解释。退出状态0被视为自愿成功的退出;ZEO和Zope服务器进程在想要停止而无需重新启动时使用此退出状态。(包括对SIGTERM的响应。)退出状态2通常用于命令行语法错误;在这种情况下,重新启动程序是没有帮助的!

注意:此机制覆盖了backoff-limit和forever选项;即,即使forever为true,列表中的子进程退出状态码也会使zdaemon放弃。要禁用此功能,请将值更改为空列表。

start-test-program

一个测试程序是否正在运行和运行的命令。如果程序正在运行,则命令应退出状态为0;否则,退出状态不为0。

start-timeout

命令行选项:-T或–start-timeout。

如果程序启动时间超过start-timeout秒,则将打印错误信息,控制脚本将以非零退出状态退出。

stop-timeout

默认为300秒(5分钟)。

当发出停止命令时,向进程发送SIGTERM信号。zdaemon等待stop-timeout秒以优雅地退出进程。如果进程在这段时间内没有退出,则发送SIGKILL信号。

user

命令行选项:-u或–user。

当zdaemon由root启动时,此选项指定zdaemon进程(以及因此的守护进程子进程)将运行的用户。这可以是用户名或数字用户ID。用户和组都通过相应的密码条目设置,使用setuid()和setgid()。这是在zdaemon执行其他任何操作(除了解析其命令行参数)之前完成的。

注意:当zdaemon不由root启动时,指定此选项是错误的。(XXX这可能是错误。)

XXX zdaemon事件日志文件可能在调用setuid()之前打开。这是好是坏?

umask

命令行选项:-m或–umask。

在守护进程模式下,此选项指定子进程的八进制umask。

default-to-interactive

如果此选项为true,当zdaemon在未提供位置命令参数的情况下调用时,将进入交互模式。如果为false,您必须使用-zdaemon的-i或–interactive命令行选项来进入交互模式。

默认启用。

logfile

命令行选项:-l或–logfile。

此选项指定默认目标为“logtail”zdaemon命令的日志文件。

注意:这不是zdaemon写入其日志消息的日志文件!该日志文件由下面的部分中描述的指定。

transcript

命令行选项:-t或–transcript。

当守护进程化时,将在其中写入正在运行的命令所有输出的文件名。

如果没有指定,命令的输出将被丢弃。

仅在启用“daemon”选项时生效。

prompt

控制器程序显示的提示。默认值必须由应用程序提供。

(注意,还有其他一些选项可用于支持旧配置文件,但现在不再需要,通常可以忽略。)

除了runner部分,您还可以使用eventlog部分指定一个或多个logfile部分

<eventlog>
  <logfile>
    path /var/log/foo/foo.log
  </logfile>

  <logfile>
    path STDOUT
  </logfile>
</eventlog>

在此示例中,日志输出发送到文件和标准输出。zdaemon的日志输出通常不太有趣,但在调试时可能很有用。

变更日志

5.1 (2024-05-03)

  • 添加对Python 3.12的支持。

  • 修复与“start-test-program”选项相关的SIGCHLD/wait引发的条件。有关详细信息,请参阅#33

5.0 (2023-05-24)

  • 停止支持Python 2.7,3.5,3.6。

4.4 (2022-12-02)

  • 添加对Python 3.8,3.9,3.10,3.11的支持。

  • 停止支持Python 3.4。

  • 停止支持使用python setup.py test运行测试。(#23)

  • 停止支持在没有安装setuptools的情况下安装此包。

4.3 (2018-10-30)

  • 添加对Python 3.6和3.7的支持。

  • 停止支持Python 3.3。

4.2.0 (2016-12-07)

  • 添加对Python 3.5的支持。

  • 停止支持Python 2.6和3.2。

4.1.0 (2015-04-16)

4.0.1 (2014-12-26)

  • 添加了对PyPy的支持。(PyPy3正在等待修复https://bitbucket.org/pypy/pypy/issue/1946的问题)。

  • 添加了对Python 3.4的支持。

  • 添加-t/--transcript命令行选项。

  • zdaemon现在可以作为模块调用,例如python -m zdaemon ...

4.0.0 (2013-05-10)

  • 添加了对Python 3.2的支持。

4.0.0a1(2013-02-15)

  • 添加了tox支持和MANIFEST.in,以进行适当的发布。

  • 添加了Python 3.3的支持。

  • 停止支持Python 2.4和2.5。

3.0.5 (2012-11-27)

  • 修复:状态命令在程序未运行时没有返回非零退出状态。这使得其他软件(例如Puppet)无法判断进程是否正在运行。

3.0.4 (2012-07-30)

  • 修复:启动命令在启动的程序失败启动(或立即退出)时以零退出状态退出。

3.0.3 (2012-07-10)

  • 修复:使用zdaemon启动的程序无法自己调用zdaemon。

3.0.2 (2012-07-10)

失败::(

3.0.1 (2012-06-08)

  • 已修复

    2.0.6中的更改,将用户的其他组设置为用户,破坏了在调用zdaemon之前通过susudo -u设置有效用户的常用配置。

    现在,如果有效用户已设置为配置的用户,则zdaemon不会设置组或有效用户。

3.0.0 (2012-06-08)

  • 添加了一个选项start-test-program,可以提供一个测试命令来测试zdaemon管理的程序是否正常运行,而不仅仅是运行。在启动程序时,启动命令不会在测试通过之前返回。例如,您可以使用此功能等待Web服务器实际接受连接。

  • 添加了start-timeout选项,如果程序启动时间过长,将会报错。这对于与start-test-program选项结合使用非常有用。

  • 添加了一个名为stop-timeout的选项,用于控制优雅关闭等待的时间。

    之前,这由backoff-limit控制,这并没有什么意义。

  • 移除了一些未文档化、未测试且可能未使用的功能。

2.0.6 (2012-06-07)

  • 修复了:当使用user选项以特定用户身份运行时,补充组没有被设置为用户的补充组。

2.0.5 (2012-06-07)

(意外发布。请忽略。)

2.0.4 (2009-04-20)

  • 版本2.0.3破坏了对相对路径到套接字(-s选项和socket-name参数)的支持,现在相对路径再次像版本2.0.2一样工作。

  • 修复了变更日志格式,使目录更易于阅读。

  • 修复了作者的电子邮件地址。

  • 移除了zpkg相关内容。

2.0.3 (2009-04-11)

  • 添加了对在Jython上引导的支持。

  • 如果运行目录不存在,将会创建它。这允许使用/var/run/mydaemon作为运行目录,当/var/run是一个tmpfs(LP #318118)时。

修复的错误

  • 不再在单元测试中使用硬编码的文件名(/tmp/demo.zdsock)。这允许你同时运行Python 2.4和2.5的测试,而不会出现虚假错误。

  • make -h现在在运行器和控制脚本中都有效。帮助信息现在由运行zdaemon脚本的用户的选项类的__doc__提供。

2.0.2 (2008-04-05)

修复的错误

  • 修复了处理环境选项时的向后不兼容更改。

2.0.1 (2007-10-31)

修复的错误

  • 修复了在环境复杂的情况下不起作用的测试重规范化器。

2.0.0 (2007-07-19)

  • 2.0.0版本的最终发布。

2.0a6(2007-01-11)

修复的错误

  • 当使用用户选项时,它仅影响运行守护进程。

2.0a3、2.0a4、2.0a5(2007-01-10)

修复的错误

  • zdaemon使用的启动守护进程管理器的新(2.0)机制破坏了一些扩展zdaemon的应用程序。

  • 添加了额外的检查来处理扩展zdaemon并复制模式但看不到ZConfig模式更新的程序。

2.0a2(2007-01-10)

新功能

  • 添加了在配置文件中设置环境变量的支持。当zdaemon用于运行需要设置环境变量(如LD_LIBRARY_PATH)的程序时,这非常有用。

  • 添加了旋转转储日志的命令。

2.0a1(2006-12-21)

修复的错误

  • 在非守护进程模式下,启动时挂起,当程序退出时产生讨厌的点。

  • 如果守护进程启动失败,启动命令会挂起并产生讨厌的点。

  • 前台和启动具有不同的语义,因为一个使用了os.system,另一个使用了os.spawn。

新功能

  • 文档

  • 现在可以为启动和前台(fg)命令提供命令行参数。

  • zdctl现在调用自身来运行zdrun。这意味着不再需要生成单独的zdrun脚本。特别是当使用目录嗅探查找和运行zdrun的魔法技术无法正确设置路径时。

  • 守护进程模式现在是默认启用。要获取非守护进程模式,您必须使用配置文件,并在其中将守护进程设置为关闭。旧-d选项保留以保持向后兼容性,但是一个无操作。

1.4a1(2005-11-21)

  • 修复了分发设置文件中的错误。

1.4a1(2005-11-05)

  • 第一次半正式发布。

某个未知版本(???)之后

  • 修改了‘zdaemon.zdoptions’在__main__.__doc__为None时不会失败的--help。

1.1之后

  • 更新了测试‘testRunIgnoresParentSignals’

o 使用‘mkdtemp’创建一个临时目录来保存测试套接字

而不是在测试目录中创建测试套接字。希望这会更稳健。有时测试目录的路径太长,无法创建测试套接字。

o 修改了‘donothing.sh’的管理。此脚本现在由

在临时目录中进行测试,并具有必要的权限。这是为了避免权限可能被破坏导致测试失败。同时,这也避免了在源树中管理文件,这算是一个额外的优势。

  • 重新排列源树以符合更常见的基于zpkg的布局

    o Python包位于‘src’下。

    o 依赖项作为‘svn:externals’添加到‘src’中。

    o 现在可以从检出目录中运行单元测试。

  • 使作为root运行时的umask导致的测试失败发出更强烈的警告。

1.1 (2005-06-09)

  • SVN标签:svn://svn.zope.org/repos/main/zdaemon/tags/zdaemon-1.1

  • 标记以使更好的‘svn:externals’链接成为可能。

待办事项

更多文档

  • 说明一些重要功能,例如

    • 工作目录

错误

  • help command

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

zdaemon-5.1.tar.gz (60.7 kB 查看哈希值)

上传时间: 源代码

构建分发

zdaemon-5.1-py3-none-any.whl (57.0 kB 查看哈希值)

上传时间: Python 3

支持者

AWSAWS 云计算和安全赞助商 DatadogDatadog 监控 FastlyFastly CDN GoogleGoogle 下载分析 MicrosoftMicrosoft PSF 赞助商 PingdomPingdom 监控 SentrySentry 错误记录 StatusPageStatusPage 状态页面