Linux I/O 到正在运行的守护进程/进程
是否可以输入/输出正在运行的进程? 我有多个游戏服务器像这样运行:
cd /path/to/game/server/binary
./binary arg1 arg2 ... argn &
如果我知道进程 ID,是否可以向服务器写入消息?
像这样的东西会很方便:
echo "quit" > process1234
其中 process1234 是进程(sid 1234)。
游戏服务器不是我编写的二进制文件,而是《使命召唤》的二进制文件。所以我无法对代码进行任何更改。
Is it possible to i/o to a running process?
I have multiple game servers running like this:
cd /path/to/game/server/binary
./binary arg1 arg2 ... argn &
Is it possible to write a message to a server if i know the process id?
Something like this would be handy:
echo "quit" > process1234
Where process1234 is the process (with sid 1234).
The game server is not a binary written by me, but it is a Call of Duty binary. So i can't change anything to the code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
是的,您可以使用管道作为其标准输入来启动进程,然后写入管道。您可以使用命名管道或匿名管道。
通常需要一个父进程来执行此操作,这将创建一个匿名管道并将其提供给子进程,因为它的 stdin - popen() 会执行此操作,许多库也实现它(例如,请参阅 Perl 的 IPC::Open2
)方法是在伪终端下运行它,这就是“屏幕”的作用。屏幕本身也可能具有执行此操作的机制。
Yes, you can start up the process with a pipe as its stdin and then write to the pipe. You can used a named or anonymous pipe.
Normally a parent process would be needed to do this, which would create an anonmyous pipe and supply that to the child process as its stdin - popen() does this, many libraries also implement it (see Perl's IPC::Open2 for example)
Another way would be to run it under a pseudo tty, which is what "screen" does. Screen itself may also have a mechanism for doing this.
仅当进程正在某处侦听某些消息时。例如,您的游戏服务器可能正在等待文件、网络连接或标准输入的输入。
如果您的进程没有主动监听某些内容,那么您真正能做的唯一事情就是停止或终止它。
现在,如果您的进程正在等待标准输入,并且您像这样运行它:
那么(在 Linux 中)您应该能够尝试以下操作:
此时您正在将标准输入输入到您的进程中。
Only if the process is listening for some message somewhere. For instance, your game server can be waiting for input on a file, over a network connection, or from standard input.
If your process is not actively listening for something, the only things you can really do is halt or kill it.
Now if your process is waiting on standard input, and you ran it like so:
Then (in linux) you should be able to try the following:
And at this point you are typing standard input into your process.
仅当流程是专门为此设计的时,您才可以这样做。
但由于您的示例请求进程退出,我建议尝试信号。首先尝试发送默认的 TERM(即终止)信号:
如果这不起作用,您可以尝试其他信号,例如 QUIT:
如果所有其他信号都失败,您可以使用 KILL 信号。这保证 (*) 停止进程,但进程不会有任何需要清理的更改:
* - 过去,如果进程在不稳定的网络上挂起,
kill -KILL
将不起作用文件服务器。不知道他们是否修复了这个问题。You can only do that if the process is explicitly designed for that.
But since you example is requesting the process quit, I'd recommend trying signals. First try to send the TERM (i.e. terminate) signal which is the default:
If that doesn't work, you can try other signals such as QUIT:
If all else fails, you can use the KILL signal. This is guaranteed (*) to stop the process but the process will have no change to clean up:
* - in the past,
kill -KILL
would not work if the process was hung when on a flaky network file server. Don't know if they ever fixed this.我很确定这会起作用,因为服务器在标准输入上有一个控制台:
您在下面的评论中提到您的进程似乎没有从 fd 0 上的控制台读取。但它必须在某些 fd 上读取。
ls -l /proc//fd/
并查找指向 /dev/pts/ 的进程(如果该进程正在gnome-terminal
中运行) code> 或 xterm 或其他东西。I'm pretty sure this would work, since the server has a console on stdin:
You mention in a comment below that your process does not appear to read from the console on fd 0. But it must on some fd.
ls -l /proc/<server pid/>/fd/
and look for one that's pointing at /dev/pts/ if the process is running in agnome-terminal
orxterm
or something.如果您想在服务器上执行一些简单的操作,请使用其他地方提到的信号。在服务器中设置信号处理程序,并让每个信号执行不同的操作,例如:
...
If you want to do a few simple operations on your server, use signals as mentioned elsewhere. Set up signal handlers in the server and have each signal perform a different action e.g.:
...
高度黑客行为,如果您有更明智的替代方案,请不要这样做,但如果您具有 ptrace 权限,则可以动态重定向进程的文件描述符。
open("/tmp/quitfile", O_RDONLY)
将文件描述符返回到/tmp/quitfile
。dup2(..., STDIN_FILENO)
用新的文件描述符替换现有的标准输入。我们使用
gdb
(但使用数字常量,因为#define
常量可能不可用)和taadaah将此代码注入到应用程序中。Highly hackish, don't do this if you have a saner alternative, but you can redirect a process's file descriptors on the fly if you have ptrace permissions.
open("/tmp/quitfile", O_RDONLY)
returns a file descriptor to/tmp/quitfile
.dup2(..., STDIN_FILENO)
replaces the existing standard input by the new file descriptor.We inject this code into the application using
gdb
(but with numeric constants, as#define
constants may not be available), and taadaah.只需在屏幕下运行它,不要将其置于后台。然后,您可以与屏幕交互地连接到它并告诉它退出,或者(带有一点预期的黑客行为)编写一个脚本来连接到屏幕,发送退出消息,然后断开连接。
Simply run it under screen and don't background it. Then you can either connect to it with screen interactively and tell it to quit, or (with a bit of expect hackery) write a script that will connect to screen, send the quit message, and disconnect.