如何写入服务的标准输入

如何写入服务的标准输入

我正在运行一个服务,它有一个连接到标准输入的 CLI。当我ssh进入机器时,我希望能够向该服务的标准输入发送命令。

系统执行程序说这StandardInput=file:/path/to/file是一个东西并且支持 FIFO。这听起来是最简单的方法。

我已经在我的~/.config/systemd/user/foo.service

[Service]
ExecStartPre=mkfifo %t/foo.stdin
ExecStart=cat -
StandardInput=file:%t/foo.stdin
ExecStopPost=rm -f %t/foo.stdin

在这个例子中,我期望当我运行以下命令时,我将看到日志中回显的输出。

echo "hello" > /run/user/1000/foo.stdin

我对此有两个问题:

  1. foo.service: Failed to set up standard input: No such file or directory。看来StandardInput=之前一定存在过ExecStartPre=。在安装过程中,我是否需要在静态位置创建永久管道,或者是否有解决方法?如果我手动创建文件并删除ExecStartPre/ ExecStopPost,那么事情就可以了。
  2. 第一个echo "command"处理得很好,但发送一个EOF并且标准输入关闭。我希望标准输入保持开放。 答案( exec 3> stdin, ..., exec 3>&-) 似乎是使用 bash FD 重定向,但这在 systemd 中不可用。

答案1

您可以创建一个插座单元对于您的 FIFO:

  • foo.socket:

    [Socket]
    ListenFIFO=%t/foo.stdin
    Service=foo.service
    
  • foo.service:

    [Service]
    ExecStart=/bin/cat -
    Sockets=foo.socket
    StandardInput=socket
    StandardOutput=journal
    StandardError=journal
    

按如下方式启动它:

systemctl --user start foo.socket

一旦 FIFO 被写入,服务本身就会启动。如果您希望它立即启动,请像这样启动它:

systemctl --user start foo.service

相关内容