有没有可能向正在运行的服务或守护进程传递输入?

6
我想创建一个在Linux上作为守护进程运行的Java控制台应用程序,我已经创建了该应用程序和脚本以将其作为后台守护进程运行。该应用程序运行并等待命令行输入。
我的问题是:
是否可能向正在运行的守护进程传递命令行输入?

抱歉,标题错误。 - Yorbenys Pardo Rodríguez
抱歉,标题错误了。想法是创建一个类似于nginx或tomcat的守护进程。例如,当守护进程正在运行时,当用户在控制台中输入“service MyserviceID --create test”时,守护进程必须能够读取此命令并执行。所有这些都不需要重新启动守护进程。 - Yorbenys Pardo Rodríguez
1
如果你正在编写服务器进程(守护进程),那么你有几个选项。你可以使用 socket命名管道,甚至是 stdin。如果服务器进程或守护进程是由其他人编写的,并且它保证从 stdin 读取,那么你可以通过 /proc/<processID>/fd/0 发送输入。 - alvits
2个回答

13

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

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

值得注意的是fd目录,它包含与该进程相关联的所有文件描述符012对于(几乎?)所有进程都存在,并且0是默认的标准输入。因此,写入/proc/$PID/fd/0将写入该进程的标准输入。
更可靠的替代方案是设置一个命名管道连接到您的进程的标准输入;然后您可以写入该管道,进程将读取它而无需依赖/proc文件系统。
请参阅ServerFault上的编写后台进程的标准输入

这需要1000倍的赞才行。 - aaron

3

上面的接受答案对我来说不太适用,所以这是我的实现方法。 为了背景,我在一个由systemctl管理的Linux守护进程上运行Minecraft服务器。我想能够发送命令到stdin(标准输入)。

首先,使用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上给出的答案。


我的服务器卡在了:Started BungeeCord Server。 - Pipe Soto
我需要比那更多的上下文。也许可以发一个新帖子并在这里链接给我? - Jake Morfe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接