是否可以对正在运行的进程进行i / o操作? 我有多个游戏服务器像这样运行:
cd /path/to/game/server/binary
./binary arg1 arg2 ... argn &
如果我知道进程ID,是否可以将消息写入服务器?
这样的东西会很方便:
echo "quit" > process1234
process1234是进程(使用sid 1234)。
游戏服务器不是我写的二进制文件,但它是一个使命召唤二进制文件。所以我无法改变代码。
答案 0 :(得分:1)
仅当进程正在某处侦听某些消息时。例如,您的游戏服务器可以等待文件,网络连接或标准输入的输入。
如果你的过程没有主动倾听某事,你唯一可以做的就是停止或杀死它。
现在,如果您的进程正在等待标准输入,并且您按原样运行它:
$ myprocess &
然后(在linux中)你应该能够尝试以下方法:
$ jobs
[1]+ Running myprocess &
$ fg 1
此时您正在为流程键入标准输入。
答案 1 :(得分:1)
如果为此明确设计了流程,则只能这样做。
但是,由于您的示例请求进程退出,我建议尝试信号。首先尝试发送默认的TERM(即终止)信号:
kill _pid_
如果这不起作用,您可以尝试其他信号,例如QUIT:
kill -QUIT _pid_
如果所有其他方法都失败,您可以使用KILL信号。这是保证(*)停止进程但该过程没有更改清理:
kill -KILL _pid_
* - 过去,如果在片状网络文件服务器上挂起进程,kill -KILL
将无效。不知道他们是否修过这个。
答案 2 :(得分:1)
我很确定这会有效,因为服务器在stdin上有一个控制台:
echo "quit" > /proc/<server pid>/fd/0
你在下面的评论中提到你的进程似乎没有从fd 0的控制台读取。但它必须在某些fd上。 ls -l /proc/<server pid/>/fd/
并查找指向/ dev / pts /的进程,如果进程在gnome-terminal
或xterm
或其他内容中运行。
答案 3 :(得分:1)
是的,您可以使用管道作为其stdin启动进程,然后写入管道。您可以使用命名或匿名管道。
通常需要一个父进程来执行此操作,这将创建一个不规则的管道并将其提供给子进程,因为它的stdin - popen()执行此操作,许多库也实现它(请参阅Perl的IPC :: Open2 for例如)
另一种方法是在伪tty下运行它,这就是“屏幕”的作用。屏幕本身也可能有这样做的机制。
答案 4 :(得分:0)
如果您想在服务器上执行一些简单的操作,请使用其他地方提到的信号。在服务器中设置信号处理程序,让每个信号执行不同的操作,例如:
...
答案 5 :(得分:0)
高度hackish,如果你有一个更健全的选择,不要这样做,但如果你有ptrace权限,你可以动态重定向进程的文件描述符。
$ echo quit > /tmp/quitfile $ gdb binary 1234 (gdb) call dup2(open("/tmp/quitfile", 0), 0) (gdb) continue
open("/tmp/quitfile", O_RDONLY)
将文件描述符返回给/tmp/quitfile
。 dup2(..., STDIN_FILENO)
替换新文件描述符的现有标准输入。
我们使用gdb
将此代码注入应用程序(但是使用数字常量,因为#define
常量可能不可用)和taadaah。
答案 6 :(得分:0)
只需在屏幕下运行它,不要背景它。然后,您可以通过交互式屏幕连接到它并告诉它退出,或者(有点期待hackery)编写一个脚本,它将连接到屏幕,发送退出消息并断开连接。