【问题标题】:Problem with non blocking fifo in bashbash中非阻塞fifo的问题
【发布时间】:2009-06-29 11:37:24
【问题描述】:

我正在运行一些军团要塞 2 服务器,我想编写一个小管理脚本。

基本上,TF2 服务器是一个提供服务器控制台的 fg 进程,因此我可以启动服务器,输入状态并从中获取答案:

***@purple:~/tf2$ ./start_server_testing 
Auto detecting CPU
Using AMD Optimised binary.
Server will auto-restart if there is a crash.

Console initialized.
[bla bla bla]
Connection to Steam servers successful.
   VAC secure mode is activated.

status

hostname: Team Fortress
version : 1.0.6.1/15 3883 secure
udp/ip  :  ***.***.133.31:27600
map     : ctf_2fort at: 0 x, 0 y, 0 z
players : 0 (2 max)

# userid name uniqueid connected ping loss state adr

太好了,现在我想创建一个脚本,将命令 sm_reloadadmins 发送到我的所有服务器。我发现做到这一点的最好方法是使用 fifo 命名管道。 现在我想做的是让这个管道只读且非阻塞到服务器进程,所以我可以写入管道并且服务器执行它,但我仍然想通过控制台写入服务器,所以如果我切换回服务器的 fg 进程,我输入 status 我想打印一个答案。

我试过这个(假设 serverfifo 是 mkfifo serverfifo):

./start_server_testing < serverfifo

不工作,服务器不会启动,直到有东西被写入管道。

./start_server_testing <> serverfifo

这实际上工作得很好,我可以看到服务器的控制台输出,我可以写入 fifo 并且服务器执行命令,但我不能再通过控制台写入服务器了。另外,如果我将“退出”写入管道(应该结束服务器)并且我在屏幕上运行它,屏幕窗口会因某种原因被杀死(为什么?)。

我只需要服务器在不阻塞的情况下读取 fifo,并且我在服务器本身上的所有键盘输入都应该发送到服务器,并且所有服务器输出都应该写入控制台。

这可能吗?如果可以,怎么做?

【问题讨论】:

  • 我假设通过使用“./start_server_testing serverfifo”我将 stdio 重新映射到 serverfifo,因此它失去了我的键盘作为 stdio。是否可以将两个源映射到进程的 stdio(在我的情况下是键盘和 serverfifo)
  • 我删除了您最近添加的内容,只是因为它不是答案。很抱歉,您认为该网站对您没有帮助,但是(重新发表评论)我看不到任何证据表明除了您自己之外任何人都“生气”了-只是有人给了您他们的想法,但不适合你想要什么...

标签: bash readonly pipe nonblocking fifo


【解决方案1】:

我意识到这与您所追求的答案不同,但您可能可以这样做using Gnu Screen

Screen 是一个制作伪 TTY 的程序。您可以使用它的功能让您共享屏幕会话。这样,您可以登录到屏幕内的服务器,您的脚本可以共享该会话,发送您可以看到的命令,然后停止共享。 process to get screen set up to allow sharing sessions is described here。它需要 root 访问权限,但如果您运行的是 TF2 服务器,我假设您有这个权限。

一旦您设置好 setuid 进程并在屏幕内显示服务器提示符,您可以让您的脚本登录到相关框,连接到屏幕,将所需的命令发送到服务器,发送 Ctrl-A,d断开与屏幕的连接,然后注销。

【讨论】:

  • 我实际上正在使用一个运行所有服务器的屏幕(CTRL+A,c 在一个屏幕中创建窗口)。我还写道:[...]and I'm running it in a screen the screen window is getting killed for some reason (wtf why?).[...] 但是现在,我可以在屏幕上写吗?我知道,如果我创建一个新屏幕,我可以以某种方式发送一个由屏幕执行然后分离的命令,但是我可以向现有屏幕发送命令吗?
  • 不用等,我认为使用管道将文本发送到进程仍然比将文本发送到屏幕更好。
  • 啊。我没听懂你在那段话里的意思。您使用 screen 的事实已经使事情变得更容易。在回答您的问题“我可以向现有屏幕发送命令吗?”时,我的回答是准确解释您将如何进行该过程。我哪里不清楚?
  • 这不是我的问题的答案。我想要一个自动化脚本,这样我就可以输入 ./reloadadmins ,它只是将 sm_reloadadmins 发送到服务器的进程。事实上,我在一个屏幕会话中使用多个窗口,据我所知,脚本只能将命令传递给屏幕会话中的活动窗口。无论如何,我不想将命令 sm_reloadadmins 发送到一台服务器,而是发送到我的所有服务器。所以我不认为 screen 是解决我的问题的好/最好的解决方案,所以我会留在命名管道上。
  • 我意识到这不是您试图解决问题的方式。但是,您正在尝试做的是对一个进程有多个输入流,而在 bash 中没有简单的方法可以做到这一点。您在上面提供的命令将输入​​和输出都重定向到来自您的 fifo,这将使控制台交互变得不可能。 -- 就多台服务器而言,您可以通过编码重复该过程来轻松地将脚本登录到服务器上。同样,您可以让它在登录时发送命令 (Ctrl A,1) 以切换窗口...
猜你喜欢
  • 1970-01-01
  • 2018-05-31
  • 2017-04-26
  • 2015-08-17
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多