因此,在我拿起斧头并摧毁我的桌面之前,我会尝试在这里询问:-)
我有一个名为 Commander.service 的套接字激活服务。由于简单,我只想将裸字符串或字符推送到此服务。
所以我有一个 Commander.socket 文件:
[Socket]
ListenFIFO=/run/commander.sk
[Install]
WantedBy=sockets.target
然后我有一个 Commander.service 文件:
[Unit]
Description=A service reading commands from the given socket
[Service]
ExecStart=/usr/bin/perl /root/commander.pl
StandardInput=socket
User=root
Group=root
Restart=no
[Install]
WantedBy=multi-user.target
现在我希望我在那里运行的脚本通过标准输入接收这些字符串或字符。
该脚本的代码是:
#!/usr/bin/env perl
my $in = *STDIN;
my $out = *STDOUT;
$out->print("My printing reaches the outside world\n");
while($_ = <$in>) {
$out->print("Received: ");
$out->print($_);
$out->print("\n");
if($_ == "1") {
$out->print("I should run the command associated with 1 ;-) \n");
} elsif($_ == "2") {
$out->print("I should run the command associated with 2 ;-) \n");
} else {
$out->print("Oh! did someone just try to trick me?\n");
}
}
$out->print("And I'm gone!\n");
通常标准输出应该与期刊对话,我也希望那里的打印能够到达期刊。
所以现在的事情是:
当我做:
echo "1" > /run/commander.sk
Commander.service 正在激活,但在日志中我只能看到日志:
Dez 22 03:18:25 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 03:31:32 phantom systemd[1]: Stopping A service reading commands from the given socket...
Dez 22 03:31:32 phantom systemd[1]: Stopped A service reading commands from the given socket.
Dez 22 03:31:41 phantom systemd[1]: Started A service reading commands from the given socket.
这意味着打印永远不会到达外界...当我更新某些内容并按应有的方式重新安装设置时,会手动停止。
我知道当我在控制台中调用 command.pl 脚本时,它确实按预期工作。从 stin 读取内容并与 stdout 对话。
我还知道,几个小时前,当我对它应该如何工作有更多误解时,打印输出确实到达了期刊......
据我所知,我没有做任何可能改变标准输出去向的事情。在此期间我做的最重要的事情就是弄清楚我最有可能需要
StandardInput=socket
行,将套接字接收为标准输入。
因为我现在已经连续第二天与这个问题作斗争了,一直把我的头发拔出来,开始对我的家具变得有攻击性^^任何帮助将非常非常感激:-)
无论如何,当前代码是 atm 在线: https://github.com/JhonnyJason/pull-deploy-commander-service
更新 使用时
StandardInput=socket
StandardOutput=journal
服务脚本就像永远积极运行,但不会在日志上给我任何输出。
注释这两行会导致从标准输入中读取不到任何内容,但我在日志中至少有标准输出。该服务也会一次又一次地被激活,直到 systemd 拒绝重新启动它。
这是 @04:05:58 运行的日志,其中注释掉了这些行。 @04:25:07 用这些线运行
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4687]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4687]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4689]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4689]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4691]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4691]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4693]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4693]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4695]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4695]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: commander.service: Start request repeated too quickly.
Dez 22 04:05:58 phantom systemd[1]: Failed to start A service reading commands from the given socket.
Dez 22 04:05:58 phantom systemd[1]: commander.service: Unit entered failed state.
Dez 22 04:05:58 phantom systemd[1]: commander.service: Failed with result 'start-limit-hit'.
Dez 22 04:25:07 phantom systemd[1]: Started A service reading commands from the given socket.
答案1
所以我有一个
commander.socket
[...]
然后我有一个commander.service
[...]
...并且您正在用 Perl 编写。
Perl 是你问题的根源。与systemd无关。所有这些与您正在执行的单位设置相关的操作都是无关紧要的,除了您必须任何一个指定StandardInput=socket
或者编写您的服务以使用文件描述符 #3。
您的服务的标准输入连接到您的 FIFO,其标准输出和错误连接到流套接字(/run/systemd/journal/stdout
,与日志通信)。
因为标准输入/输出文件描述符不是终端设备,所以 Perl 不是行缓冲,也不是单元缓冲其 I/O;它正在完全缓冲它。
当标准输出不是终端设备时,没有显式切换到单元缓冲(“autoflush”),但它是当输出发生时,您希望在某处(例如日志)立即看到输出,这是一个非常常见的 Perl 错误。
因此,通过使标准输出“热”/“自动刷新”来打开单元缓冲。
进一步阅读
- 布赖恩·D·福伊. ”如何刷新/取消缓冲输出文件句柄?为什么我必须这样做?”。Perl 5 文档。 perl.org。
$|
。 “佩尔瓦尔”。 Perl 5 文档。 perl.org。- 马克·杰森·多米纳斯 (1998)。 ”遭受缓冲之苦?”。 Perl 杂志。珩鸟网站。