gpt4 book ai didi

bash - 通过映射到stdin的套接字与Systemd服务进行通信

转载 作者:行者123 更新时间:2023-12-03 12:02:12 25 4
gpt4 key购买 nike

我正在创建我的第一个后台服务,并且想通过套接字与之通信。
我有以下脚本/tmp/myservice.sh:

#! /usr/bin/env bash

while read received_cmd
do
echo "Received command ${received_cmd}"
done
和以下套接字 /etc/systemd/user/myservice.socket
[Unit]
Description=Socket to communicate with myservice

[Socket]
ListenSequentialPacket=/tmp/myservice.socket
以及以下服务:
[Unit]
Description=A simple service example

[Service]
ExecStart=/bin/bash /tmp/myservice.sh
StandardError=journal
StandardInput=socket
StandardOutput=socket
Type=simple
这个想法是要了解如何与后台服务进行通信,这里使用unix文件套接字。该脚本从 shell 启动并读取stdin时效果很好,我认为通过设置 StandardInput = "socket"可以从套接字以相同方式读取。
但是,当我运行 nc -U /tmp/myservice.socket时,该命令立即返回,并且我得到以下输出:
$ journalctl --user -u myservice
-- Logs begin at Sat 2020-10-24 17:26:25 BST, end at Thu 2020-10-29 14:00:53 GMT. --
Oct 29 08:40:16 shiny systemd[1689]: Started A simple service example.
Oct 29 08:40:16 shiny bash[21941]: /tmp/myservice.sh: line 3: read: read error: 0: Invalid argument
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Succeeded.
Oct 29 08:40:16 shiny systemd[1689]: Started A simple service example.
Oct 29 08:40:16 shiny bash[21942]: /tmp/myservice.sh: line 3: read: read error: 0: Invalid argument
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Succeeded.
Oct 29 08:40:16 shiny systemd[1689]: Started A simple service example.
Oct 29 08:40:16 shiny bash[21943]: /tmp/myservice.sh: line 3: read: read error: 0: Invalid argument
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Succeeded.
Oct 29 08:40:16 shiny systemd[1689]: Started A simple service example.
Oct 29 08:40:16 shiny bash[21944]: /tmp/myservice.sh: line 3: read: read error: 0: Invalid argument
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Succeeded.
Oct 29 08:40:16 shiny systemd[1689]: Started A simple service example.
Oct 29 08:40:16 shiny bash[21945]: /tmp/myservice.sh: line 3: read: read error: 0: Invalid argument
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Succeeded.
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Start request repeated too quickly.
Oct 29 08:40:16 shiny systemd[1689]: myservice.service: Failed with result 'start-limit-hit'.
Oct 29 08:40:16 shiny systemd[1689]: Failed to start A simple service example.
我是否误解了套接字的工作方式?为什么 read无法从套接字读取?我是否应该使用另一种机制与后台服务进行通信(如我所说,这是我的第一个后台服务,所以我可以在这里做一些非常规的事情)?

最佳答案

我看到的使用shell脚本的唯一一件事就是ListenStream=而不是ListenSequentialPacket=。 (显然,这意味着您会丢失数据包边界,但是读取 shell 程序通常会定向为从流中读取以\n结尾的行,因此通常不会出现问题)。
但是最重​​要的是缺少的是额外的Accept行:

[Socket]
ListenStream=...
Accept=true
据我了解,没有此服务,服务将被传递给套接字,它必须首先在其上进行套接字 accept()调用,以获得实际的连接套接字(因此 read错误)。然后,该服务还必须处理所有其他连接。
通过使用 Accept=true,将为每个新连接启动一个新服务,并将该服务传递给立即可用的套接字。但是请注意,这意味着该服务现在必须被模板化,即称为 myservice@.service而不是 myservice.service
(对于数据报套接字,必须将 Accept保留默认值为false)。参见 man systemd.socket

关于bash - 通过映射到stdin的套接字与Systemd服务进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64594843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com