2014-01-23 38 views
1

我經常必須重新啓動服務器才能查看我的更改是否正常。我保持這個服務器在一個shell中打開,所以我可以快速訪問當前日誌。所以這裏是我在我的shell中輸入的內容:^C!!⏎。那是send SIGINT,然後是relaunch last event in history如何停止當前的前臺進程並重新執行它?

所以我想輸入的是^R,結果相同。

(注:我使用的zsh)

我試過如下:

relaunch-function() { 
     kill -INT %% && !! 
} 
zle -N relaunch-widget relaunch-function 
bindkey "^R" relaunch-widget 

但似乎運行我的服務器,同時,^ R將不壽的外殼,但傳遞給服務器它沒有注意到shell。所以我看不到一個通用的解決方案,而測試返回值和進程名稱應該是可行的。

回答

1

只要作業在前臺運行,鍵就不會傳遞到shell。因此,設置一個用於殺死前臺進程的鍵綁定並重新啓動它將不起作用。

但是,您可以在無限循環中啓動服務器,以便它自動重新啓動。假設命令的名稱是run_server你可以象這樣開始的外殼:

(TRAPINT(){};while sleep .5; do run_server; done) 

周圍的括號啓動一個子shell,TRAPINT(){}禁用SIGINT這個殼。 while循環將繼續重新啓動run_server,直到sleep以非零的退出狀態退出。這可以通過用^C中斷sleep來實現。 (沒有設置TRAPINT,中斷run_server也可能中斷循環)

所以如果你想重新啓動你的服務器,只需按^C並等待0.5秒。如果您想在不重新啓動的情況下停止服務器,請在0123秒鐘內按^C兩次。

爲了節省一些打字,你可以爲創建一個函數:

doloop() {(
    TRAPINT(){} 
    while sleep .5 
    do 
     echo running \"[email protected]\" 
     eval [email protected] 
    done 
)} 

然後用doloop run_server調用它。注意:由於函數本身並不打開子shell,因此您仍需要額外的()

eval允許使用殼結構。例如doloop LANG=C locale。在某些情況下,您可能需要使用(單個):

$ doloop echo $RANDOM 
running "echo 242" 
242 
running "echo 242" 
242 
running "echo 242" 
242 
^C 
$ doloop 'echo $RANDOM' 
running "echo $RANDOM" 
10988 
running "echo $RANDOM" 
27551 
running "echo $RANDOM" 
8910 
^C 
+0

太好了,謝謝。現在我遇到了一個小問題,試圖啓動'LANG = C。/ run_server'將不起作用,並給出'doloop:5:command not found:LANG = C'。我大部分時間都和我的本地人聊天,但在這裏我想訪問原始日誌,翻譯無助於調試。 – psychoslave

+0

也就是說,因爲具有單個「$ @」的行不由shell進行評估。我更新了腳本以使用'eval $ @'。 – Adaephon

+0

謝謝。我還用'輸入setaf 6'和'輸入setaf 7'來包裝回聲,以便我可以輕鬆地看到重新開始的位置。 – psychoslave

相關問題