2010-01-01 105 views
2

运行进程的I/O有可能吗? 我已经跑这样的多个游戏服务器:运行后台进程的Linux I/O /进程

cd /path/to/game/server/binary 
./binary arg1 arg2 ... argn & 

是否有可能写一个消息到服务器,如果我知道进程的ID?

像这样的事情会很方便:

echo "quit" > process1234 

哪里process1234是过程(与SID 1234)。

游戏服务器不是我写的二进制文件,但它是Call of Duty二进制文件。所以我不能改变任何代码。

+0

用更一般的建议编辑我的回复。 – Omnifarious 2010-01-02 01:20:39

回答

1

是的,您可以使用管道作为标准输入启动进程,然后写入管道。您可以使用命名管道或匿名管道。

通常情况下需要一个父进程来执行此操作,它将创建一个不可分的管道并将其作为stdin - popen()提供给子进程,许多库也实现它(请参见Perl的IPC :: Open2例如)

另一种方法是在伪tty下运行它,这是“屏幕”所做的。屏幕本身也可能有这样做的机制。

+0

我想我去使用屏幕。首先我要学习如何使用它:P – VDVLeon 2010-01-01 23:25:02

+1

GNU屏幕还有其他选择,例如http://www.cliki.net/detachtty和http://caca.zoy.org/wiki/neercs - 实际上,前者可能会更简单地以编程方式进行交互。 – ephemient 2010-01-04 03:10:13

1

只有当进程正在侦听某个消息。例如,您的游戏服务器可能正在等待文件输入,网络连接输入或标准输入。

如果你的过程没有积极地倾听某些事情,你唯一能做的就是暂停或者杀死它。

现在,如果你的过程是在标准输入等待,你运行它,像这样:

$ myprocess & 

然后(在Linux),你应该可以尝试以下方法:

$ jobs 
[1]+ Running     myprocess & 
$ fg 1 

而且此时您正在将标准输入输入到您的流程中。

+0

服务器有一个命令输入控制台。该命令退出退出服务器。我可以杀死,但后来我搞砸了日志文件。所以我想退出服务器,因为它应该是。所以服务器听stdin。 – VDVLeon 2010-01-01 21:06:35

+0

工作不存在(已经)。可能是因为服务器是由cronjob脚本启动,然后没有存储任何作业? – VDVLeon 2010-01-01 21:37:01

1

你只能这样做,如果过程是明确的设计。

但是,既然你的例子是请求过程退出,我建议尝试信号。首先尝试发送TERM(即终止)信号,这是默认的:

kill _pid_ 

如果不工作,你可以尝试其他的信号,如QUIT:

kill -QUIT _pid_ 

如果一切都失败,你可以使用KILL信号。这是保证(*)停止的过程,但过程不会有任何改变,清理:

kill -KILL _pid_ 

* - 在过去,kill -KILL不会,如果这个过程是挂工作片状网络文件服务器上时。不知道他们是否修复过这个问题。

+0

“D”状态有很多原因(http://en.wikipedia.org/wiki/Uninterruptible_sleep),等待NFS I/O成为更常见的情况之一。 Linux一直在朝着消除其中一些倾向于可中断睡眠的方向前进,但如果中断,许多系统调用都不可能重新启动。 – ephemient 2010-01-04 05:25:26

1

我敢肯定这会工作,因为服务器对标准输入控制台:

echo "quit" > /proc/<server pid>/fd/0 

你提到在下面,你的过程中不会出现,从控制台上的fd 0阅读评论。但它必须在一些fd上。 ls -l /proc/<server pid/>/fd/,如果进程在gnome-terminalxterm或其他东西中运行,找一个指向/ dev/pts /的目录。

+0

如果我运行:ln -al/proc//fd/0我得到: lr-x ------ 1 root root 64 jan 1 23:00 0 - >/dev/null 所以没有输入流。 我记得我的东西。服务器有一个控制台输入行,总是在你的linux控制台的底部。所以也许它使用ncurses(或其他)来读取输入。也许那个控制台输入行有另一个fd? – VDVLeon 2010-01-01 21:40:53

0

如果你想在你的服务器上做一些简单的操作,使用其他地方提到的信号。在服务器中设置信号处理程序,并让每个信号执行不同的操作,例如:

  • SIGINT:重读配置文件
  • SIGHUP:退出

...

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/quitfiledup2(..., STDIN_FILENO)用新的文件描述符替换现有的标准输入。

我们使用gdb(但使用数字常量,因为#define常量可能不可用)和taadaah将此代码注入应用程序。

0

只需在屏幕下运行它,不要背景。然后,您可以通过交互方式与屏幕进行连接并告诉它退出,或者(有一点期望hackery)编写将连接到屏幕的脚本,发送退出消息并断开连接。