2010-01-01 84 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)編寫將連接到屏幕的腳本,發送退出消息並斷開連接。