如何制作将输出发送到进程的shell脚本


11

我目前正在屏幕上运行服务器控制台程序,因为我既需要阅读它,也需要偶尔发送命令。

我想在后台将应用程序作为守护程序运行(使用init启动/停止)。

我可以tail -f记录日志,但是那不能让我向过程发送输入。

有什么方法可以进行设置,以便我既可以读取也可以发送输入,但仍在后台运行它?

我还希望能够从不同的进程向守护程序发送输入(例如,可以发送“ Stop \ n”命令的shell脚本)。


只是对要阅读此书的任何人的评论—这里的答案很棒。如果您不知道命名管道,我强烈建议您至少尝试一下。使用此工具,我可以将Minecraft作为服务运行,并通过写入命名管道来通过其他脚本与控制台进行交互-因此可以编写脚本以停止服务器,向用户发送消息等,同时仍然解析输出日志查找关键行(例如将发给用户的聊天消息作为文本发送给他)
比尔K

Answers:


9

从管道读取,写入文件

如果希望守护程序读取某个任意进程产生的输入,则需要将该进程连接到管道。在这里,任意过程是您回显命令,它将在不同的上下文中运行。因此,创建一个命名管道(在Unix上下文中通常称为fifo)。

mkfifo /var/run/daemon.fifo
</var/run/daemon.fifo /path/to/daemond --option >daemon.log

只需将命令写入管道:

echo 'FORWARD 10' >/var/run/daemon.fifo
echo 'LEFT 72' >/var/run/daemon.fifo

但是,这不太可能正常工作:当守护程序在其标准输入上看到文件结束时,它很有可能会退出,该守护进程会在写入管道的第一个进程终止时立即发生。您可以tail -f用来避免该问题。

</var/run/daemon.fifo tail -c +1 -f | {
  echo $$ >/var/run/daemon.pid
  exec /path/to/daemond --option >daemon.log
}

在某些tail实现中,您可能会因缓冲而受苦:该tail进程将等待,直到它积累了足够的字节以发出一些输出为止。我认为这在POSIX工具箱中无法解决;如果存在问题,请使用普通的C或Perl或Python程序。据我所知,tail从GNU coreutils(在Linux和其他地方可以找到)在这方面是安全的。

当您停止守护程序时,echo >/var/run/daemon.fifo将终止该进程tail


在屏幕内启动程序

而不是直接从服务管理器中调用守护程序(实际上是在使用SysV init还是其他诸如包装脚本或Upstart之类的东西),而是调用

screen -c daemon.screenrc -L -d -m -S daemon_name /path/to/daemond --option

由于守护程序将不是服务管理器的子进程,因此您需要确保将信号发送到正确的进程。该如何执行取决于守护程序的启动方式以及启动方式。

技术上讲,可以将正在运行的进程附加到终端上,但是有使程序崩溃的风险,因此对于生产系统来说绝对是这样。

-L选项使屏幕将其窗口中出现的所有内容写入文件。文件名daemon.screenrclogfile指令指定。


实际上,我真的很想能够从脚本向stdin发送消息-也许这就是我应该问的问题。目前,我只是通过脚本运行服务器,并能够在终端中键入该服务器,但似乎它应该作为服务运行...
Bill K 2010年

@比尔:好的,我明白了。然后我想到的第一件事是一个命名管道。
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

我想这正是我想要的@Gilles!我需要更好地理解它。我将花一些时间整理手册页以弄清它-老实说我很少得到(我得到了您正在做的大部分事情,几乎没有得到您如何做的事情-我以为我有点我的理论不是要直接连接到流程,而是要创建另一个脚本,将其I / O与守护进程O / I连接起来,以使其看起来像原始控制台正在运行,但是具有这种能力同时在另一个脚本中执行回显“ FORWARD 10”。
Bill K

我想我得到了很多。如果我将其分解,我现在可以理解“ mkfifo管道”和“ tail -f管道|命令>输出”,对它们进行了测试,它们就可以工作。我认为您拥有的其他大多数东西都是使它可以在一行上运行的技巧-我错过了任何关键的东西吗?
Bill K

@Bill:您可以从外部将终端写入屏幕内部(使用屏幕的stuff命令)。但是您在这里不需要终端的开销(处理,但最重要的是认知),管道就足够了(用一个忽略文件结尾的中继过程就足够了)。你可能想尝试一点与<fifo cat<fifo tail -f | cat在一个终端,并echo >fifo; echo >fifo在另一端; 我想你会没事的。
吉尔(Gilles)“所以,别再邪恶了”,2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.