WoJ Asked: 2018-08-09 23:39:03 +0800 CST2018-08-09 23:39:03 +0800 CST 2018-08-09 23:39:03 +0800 CST 如果它是由systemd启动的服务进程,如何检查一个程序?[复制] 772 是否有记录的方法可以从作为服务本身运行的程序的代码中检查它是否已启动systemd(而不是从交互式登录会话中、从 cron 等启动)? 我当前的解决方案是在.service单元 ( Environment=...) 中定义一个环境变量,并检查它在我的代码中是否存在。但可能有一些直接可用的东西。 systemd services 2 个回答 Voted Best Answer JdeBP 2018-08-10T03:18:06+08:002018-08-10T03:18:06+08:00 一个不能。 systemd 为服务调用的进程提供的一切——它的参数、它的环境、包含它的控制组、它的资源限制、它的打开文件描述符——也可以并且由其他服务管理器完成。此外,没有共同的约定来识别哪些服务管理器正在管理服务。没有常规的环境变量,也没有其他标记。 错误的机制 您可能正在考虑检查父进程的可执行名称。这是一个非首发,原因在https://unix.stackexchange.com/a/196252/5132中阐述。父进程(用于系统范围的服务)的可执行程序映像的名称将/sbin/init在 Debian Linux 操作系统上,因为 Debian 的约定是它是实际进程 1 程序映像文件的替代样式符号链接,并且initramfs中的/init程序只需要知道那个名字。 你可能会想,尽管我刚刚写了,控制组是一个系统标记。他们不是。这是一个由完全不同的服务管理器管理的服务进程的控制组树,service-manager来自 nosh 工具集: % systemd-cgls /system.slice/service-manager.service/[email protected] 控制组/system.slice/service-manager.service/[email protected]: └─[email protected] └─1433 tinydns % 该tinydns程序在 中找到一个控制组/proc/self/cgroup,没有理由假设 systemd 设置了该控制组。它实际上是由move-to-control-group实用程序设置的: % 猫 /var/local/sv/[email protected]/service/run #!/bin/nosh #运行从./[email protected]生成的文件 #DNS/UDP 套接字在 127.53.0.1 udp-socket-listen --systemd-compatibility --combine4and6 127.53.0.1 域 移动到控制组“../[email protected]/[email protected]” 环境目录 enuidgid -- tinydns -d setlogin -- tinydns -d 硬限制 -d 3000000 softlimit -d 硬 。/服务 % 没有其他进程状态更改是 systemd 独有的。环境变量可以用setenv(链加载工具) userenv, machineenv, 或export(链加载工具), 资源限制用softlimit, ulimit(链加载工具), 或s6-softlimit, 打开文件描述符用redirfdor fdredir, 命名空间用unshare, 调度优先级用rtprio或chrt, NUMA 策略与numactl; 等等。 systemd 不是该LISTEN_FDS协议的唯一发言人,从前面可以看出。 INVOCATION_ID同样只是在程序env/INVOCATION_ID开始时填充run和链接的练习envdir。这些都不是可靠的标记。 概念错误 还有一个缺陷是您要排除由cron. 这里的概念缺陷是它cron是一个服务,它产生的进程是在该服务的上下文中运行的。由服务中的进程产生的进程和由其他服务中的某个其他服务进程产生的进程之间没有神奇的区别,这使得前者在某种程度上与后者区分开来。croncron 摆脱这个概念上的错误,答案就会出现。守护进程的区别在于它们所属的(POSIX)会话没有控制终端,并且它们没有其他关联(从setlogin通过 systemd 的用户空间登录会话机制设置的名称到各种安全上下文)与任何登录会话。没有可移植的直接方法来查询会话的控制终端是什么,但请注意打开/dev/tty失败是可用的间接路由。请注意,一些表面上很有前途的 C 库函数实际上在实践中并不可靠。 进一步阅读 https://unix.stackexchange.com/a/398951/5132 https://unix.stackexchange.com/a/187540/5132 如何获取控制终端的真实姓名? 工具集: s6。劳伦特·伯科特。skarnet.org。 执行线。劳伦特·伯科特。skarnet.org。 乔纳森·德博因·波拉德 (2018)。诺什。 软件。 参考手册: export. 劳伦特·伯科特。 执行线。skarnet.org。 redirfd. 劳伦特·伯科特。 执行线。skarnet.org。 s6-softlimit. 劳伦特·伯科特。 s6。skarnet.org。 芯片。运行。格里特佩佩。smarden.org。 乔纳森·德博因·波拉德 (2018)。service-manager. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。move-to-control-group. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。setenv. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。softlimit. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。ulimit. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。fdredir. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。unshare. 小吃指南。软件。 乔纳森·德博因·波拉德 (2018)。setlogin. 小吃指南。软件。 perror 2018-08-09T23:57:44+08:002018-08-09T23:57:44+08:00 我想您可以使用以下命令: #> systemctl list-unit-files --state=enabled cups.path enabled accounts-daemon.service enabled anacron.service enabled apparmor.service enabled atd.service enabled [email protected] enabled avahi-daemon.service enabled ... 单独systemctl list-unit-files列出所有可能启动服务的已安装单元文件。标记为的那些enabled是在您键入命令时启动的。
一个不能。
systemd 为服务调用的进程提供的一切——它的参数、它的环境、包含它的控制组、它的资源限制、它的打开文件描述符——也可以并且由其他服务管理器完成。此外,没有共同的约定来识别哪些服务管理器正在管理服务。没有常规的环境变量,也没有其他标记。
错误的机制
您可能正在考虑检查父进程的可执行名称。这是一个非首发,原因在https://unix.stackexchange.com/a/196252/5132中阐述。父进程(用于系统范围的服务)的可执行程序映像的名称将
/sbin/init
在 Debian Linux 操作系统上,因为 Debian 的约定是它是实际进程 1 程序映像文件的替代样式符号链接,并且initramfs中的/init
程序只需要知道那个名字。你可能会想,尽管我刚刚写了,控制组是一个系统标记。他们不是。这是一个由完全不同的服务管理器管理的服务进程的控制组树,
service-manager
来自 nosh 工具集:该
tinydns
程序在 中找到一个控制组/proc/self/cgroup
,没有理由假设 systemd 设置了该控制组。它实际上是由move-to-control-group
实用程序设置的:没有其他进程状态更改是 systemd 独有的。环境变量可以用
setenv
(链加载工具)userenv
,machineenv
, 或export
(链加载工具), 资源限制用softlimit
,ulimit
(链加载工具), 或s6-softlimit
, 打开文件描述符用redirfd
orfdredir
, 命名空间用unshare
, 调度优先级用rtprio
或chrt
, NUMA 策略与numactl
; 等等。systemd 不是该
LISTEN_FDS
协议的唯一发言人,从前面可以看出。INVOCATION_ID
同样只是在程序env/INVOCATION_ID
开始时填充run
和链接的练习envdir
。这些都不是可靠的标记。概念错误
还有一个缺陷是您要排除由
cron
. 这里的概念缺陷是它cron
是一个服务,它产生的进程是在该服务的上下文中运行的。由服务中的进程产生的进程和由其他服务中的某个其他服务进程产生的进程之间没有神奇的区别,这使得前者在某种程度上与后者区分开来。cron
cron
摆脱这个概念上的错误,答案就会出现。守护进程的区别在于它们所属的(POSIX)会话没有控制终端,并且它们没有其他关联(从
setlogin
通过 systemd 的用户空间登录会话机制设置的名称到各种安全上下文)与任何登录会话。没有可移植的直接方法来查询会话的控制终端是什么,但请注意打开/dev/tty
失败是可用的间接路由。请注意,一些表面上很有前途的 C 库函数实际上在实践中并不可靠。进一步阅读
export
. 劳伦特·伯科特。 执行线。skarnet.org。redirfd
. 劳伦特·伯科特。 执行线。skarnet.org。s6-softlimit
. 劳伦特·伯科特。 s6。skarnet.org。service-manager
. 小吃指南。软件。move-to-control-group
. 小吃指南。软件。setenv
. 小吃指南。软件。softlimit
. 小吃指南。软件。ulimit
. 小吃指南。软件。fdredir
. 小吃指南。软件。unshare
. 小吃指南。软件。setlogin
. 小吃指南。软件。我想您可以使用以下命令:
单独
systemctl list-unit-files
列出所有可能启动服务的已安装单元文件。标记为的那些enabled
是在您键入命令时启动的。