是否可以将输入传递给正在运行的服务或守护进程?

Posted

技术标签:

【中文标题】是否可以将输入传递给正在运行的服务或守护进程?【英文标题】:Is it possible to pass input to a running service or daemon? 【发布时间】:2017-04-05 13:42:55 【问题描述】:

我想创建一个在 Linux 上作为守护程序运行的 Java 控制台应用程序,我已经创建了应用程序和脚本以将应用程序作为后台守护程序运行。应用程序运行并等待命令行输入。

我的问题:

是否可以将命令行输入传递给正在运行的守护进程?

【问题讨论】:

对不起,标题写错了。 对不起,标题写错了。这个想法是创建一个像 nginx 或 tomcat 一样工作的守护进程。例如,守护程序正在运行,当用户在控制台中键入:“service MyserviceID --create test”时,守护程序必须能够读取此命令并执行操作。所有这一切都无需重新启动守护进程 如果您正在编写服务器进程(守护进程),那么您有多种选择。您可以使用socketnamed pipes 甚至stdin。如果服务器进程或守护进程是由其他人编写的,并保证从标准输入读取,您可以通过/proc/<processID>/fd/0 发送输入。 【参考方案1】:

在 Linux 上,所有正在运行的进程在 /proc 下都有一个特殊目录,其中包含进程的信息和挂钩。 /proc 的每个子目录都是一个正在运行的进程的 PID。因此,如果您知道特定进程的 PID,您可以获得有关它的信息。例如:

$ sleep 100 & ls /proc/$!
...
cmdline
...
cwd
environ
exe
fd
fdinfo
...
status
...

值得注意的是fd 目录,其中包含与进程关联的所有file descriptors。 012 存在于(几乎?)所有进程中,0 是默认标准输入。所以写到/proc/$PID/fd/0 会写到那个进程的标准输入。

更强大的替代方法是设置named pipe 连接到您的进程的标准输入;然后您可以写入该管道,该进程将读取它而无需依赖/proc 文件系统。

另请参阅 ServerFault 上的 Writing to stdin of background process。

【讨论】:

这需要 1000 倍以上的更新【参考方案2】:

上面接受的答案对我来说不太适用,所以这是我的实现。 对于上下文,我在使用systemctl 管理的 Linux 守护程序上运行 Minecraft 服务器。我希望能够向stdin (StandardInput) 发送命令。

首先,使用mkfifo /home/user/server_input在某处创建一个FIFO文件。

[Service]
ExecStart=/usr/local/bin/minecraft.sh
StandardInput=file:/home/user/server_input

然后,在您的守护进程*.service 文件中,执行运行您的服务器或后台程序的 bash 脚本,并将 StandardInput 指令设置为我们刚刚创建的 FIFO 文件。 在minecraft.sh 中,以下是运行服务器并将输入通过管道传输到正在运行的服务的控制台的关键命令。

tail -f /home/user/server_input| java -Xms1024M -Xmx4096M -jar /path/to/server.jar nogui

最后,运行 systemctl start your_daemon_service 并传递输入命令,只需使用:

echo "command" > /home/user/server_input

感谢ServerFault上给出的答案

【讨论】:

以上是关于是否可以将输入传递给正在运行的服务或守护进程?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Python 脚本像 Linux 中的服务或守护程序一样运行

Linux守护进程详解

在 XPC 服务守护进程中查看可用的字典?

是否可以在 Docker 中运行 syslog 并将其作为主机的 syslog 守护进程公开给主机?

如何检查 impala 守护进程实例和状态存储守护进程实例是不是正在运行?

Linux 守护进程