我当前的服务和 Shell 脚本
我有一个名为的 systemd 服务文件myservice.service
。该服务在启动时启动。该服务启动 shell 脚本/usr/bin/myscript.sh
,如下面的部分所示[Service]
:
...
[Service]
Type=forking
ExecStart=/usr/bin/myscript.sh
PIDFile=/dev/shm/myscript.pid
...
脚本内容如下:
#!/bin/sh
/usr/bin/script-python.py > /dev/null &
echo $! > /dev/shm/myscript.pid
shell 脚本myscript.sh
启动 Python 脚本:script-python.py
。通过重定向,> /dev/null
的标准输出script-python.py
被发送到/dev/null
,因此丢失。
更改为使用 Service->StandardOutput=null
在StandardOutput 的 systemd 文档中我读到了以下句子:
null将标准输出连接到 /dev/null,即写入其中的所有内容都将丢失。
因此,我考虑对我的文件执行以下更改:
myservice.service
变为(添加StandardOutput=null
):
...
[Service]
Type=forking
ExecStart=/usr/bin/myscript.sh
PIDFile=/dev/shm/myscript.pid
StandardOutput=null
...
myscript.sh
变为(删除>/dev/null
):
#!/bin/sh
/usr/bin/script-python.py &
echo $! > /dev/shm/myscript.pid
我的问题
我的问题是:如果我进行上述修改,结果与我现在的情况完全相同:所有输出都script-python.py
丢失了?没有任何区别吗?
这两者几乎是等价的:
和
第一个会将脚本
stdout
的重定向.py
到/dev/null
。第二个会将stdout
整个sh
脚本的 重定向到/dev/null
。在这种情况下,它们是等效的,但如果您的sh
脚本包含其他行,它们不会被静音(只是script-python.py
)。正如我在评论中提到的,您的脚本似乎是为较旧的 SysV init 系统编写的。它可以与
systemd
with配合使用Type=forking
,但它明确地执行了本systemd
应自动为您完成的操作。如果我要将其集成到我的一台机器上,我会删除
/usr/bin/myscript.sh
并使用这个服务文件:您可以看到这要简单得多。
只要
script-python.py
不会向 stdout 发送垃圾邮件,我可能还会删除该StandardOutput=
行并让它journald
处理它。我有时会看到人们使用,>/dev/null
因为他们从终端手动运行脚本,并希望将该终端重新用于其他事情而不受 stdout 的干扰。当它是一项服务时,这不是一个问题。以下是对每一行更改的解释:
ExecStart=/usr/bin/script-python.py
:Systemd 可以直接运行 Python 脚本。这在 SysV init 中是不可能的。这避免了不必要地调用sh
。Type=forking
:sh
您最初拥有的脚本将 fork (&
),允许script-python.py
在后台运行。这就是服务过去的工作方式。由于我们script-python.py
直接运行,因此我们不需要这个。默认设置会导致 systemd直接Type=simple
监视。script-python.py
PIDFile=
:仅与 一起使用Type=forking
。它有助于systemd
了解应将哪个分叉进程作为主进程进行跟踪。systemd
如果只有一个子进程,则可以很好地猜测,因此无论如何它都可能已被删除。其他几点说明:
您的
PIDFile=
位于/dev/shm/
。放置它的位置很奇怪,因为该设备通常由共享内存调用来管理。/run/script-python.pid
如果您决定保留它,会更合适。sysV init 脚本会将 PID 保存到文件中,以便稍后检索以停止/重新启动。在
systemd
管理服务时,这没有必要,因为 PID 是在内部跟踪的,并且终止信号由其他选项定义。然后用户可以使用以下命令启动/停止脚本
现已替换为