bash 中非阻塞 fifo 的问题
我正在运行一些《军团要塞 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 进程,我输入状态我想要打印答案。
我尝试了这个(假设 serverfifo 是 mkfifo serverfifo):
./start_server_testing < serverfifo
不工作,服务器不会启动,直到有东西写入管道。
./start_server_testing <> serverfifo
这实际上工作得很好,我可以看到服务器的控制台输出,我可以写入 fifo 并且服务器执行命令,但我无法再通过控制台写入服务器。 另外,如果我向管道写入“退出”(这应该结束服务器)并且我在屏幕中运行它,则屏幕窗口会由于某种原因被杀死(wtf为什么?)。
我只需要服务器在不阻塞的情况下读取 fifo,并且服务器本身上的所有键盘输入都应该发送到服务器,并且所有服务器输出都应该写入控制台。
这可能吗?如果可以,如何实现?
I'm running a few Team Fortress 2 servers and I want to write a little management script.
Basically the TF2 servers are a fg process which provides a server console, so I can start the server, type status and get an answer from it:
***@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
Great, now I want to create a script which sends the command sm_reloadadmins to all my servers. The best way I found to do this is using a fifo named pipe.
Now what I want to do is having this pipe readonly and non blocking to the server process, so I can write into the pipe and the server executes it, but still I want to write via console one the server, so if I switch back to the fg process of the server and I type status I want an answer printed.
I tried this (assuming serverfifo is mkfifo serverfifo):
./start_server_testing < serverfifo
Not working, the server won't start until something is written to the pipe.
./start_server_testing <> serverfifo
Thats actually working pretty good, I can see the console output of the server and I can write to the fifo and the server executes the commands, but I can't write via console to the server anymore. Also, if I write 'exit' to the pipe (which should end the server) and I'm running it in a screen the screen window is getting killed for some reason (wtf why?).
I only need the server to read the fifo without blocking AND all my keyboard input on the server itself should be send to the server AND all server ouput should be written to the console.
Is that possible? If yes, how?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我意识到这不是您所追求的答案,但您可能可以这样做 使用 Gnu Screen。
Screen 是一个制作伪 TTY 的程序。 您可以使用它的功能来共享屏幕会话。 这样,您就可以登录到屏幕内的服务器,并且您的脚本可以共享该会话,发送您可以看到的命令,然后停止共享。 将屏幕设置为允许共享会话的过程如下所述< /a>. 它需要 root 访问权限,但我假设如果您运行的是 TF2 服务器,您就拥有 root 访问权限。
设置 setuid 进程并在屏幕内显示服务器提示符后,您可以让脚本登录到相关框,连接到屏幕,将所需的命令发送到服务器,发送 Ctrl-A,d 断开连接屏幕,然后注销。
I realize this isn't an answer in the same vein as you were pursuing, but you can probably do this using Gnu Screen.
Screen is a program that makes a pseudo-TTY. You can use its ability to let you share a screen session. This way, you can be logged in to the server inside of screen, and your script can share that session, send a command which you can see, and then stop sharing. The process to get screen set up to allow sharing sessions is described here. It requires root access, but I'm presuming you have that if you're running a TF2 server.
Once you get the setuid process set up and have the server prompt inside of screen, you can have your script log in to the relevant box, connect to screen, send the desired command to the server, send Ctrl-A,d to disconnect from screen, and then logout.