2007-12-09

你有 screen 時而不起的困擾嗎?看看這個吧

00:31 jnlin> puttytray真好用XD
00:34 yhchan> jnlin++
00:34 chinsan> jnlin: puttytray 我覺得不太好用 XD 若有內建 tab 的 putty 會比較好
00:35 jnlin> chinsan: tab!
00:35 jnlin> chinsan: 我是覺得有 screen 就很好用了 XD
00:37 chinsan> jnlin: screen 有時候 -r 或 -x (機率更高) 會當啊...到時候連的一大堆機器都要重來一次..
00:37 superd> 有的時候,還是得開二個 putty ><"
00:38 chinsan> wintabber 則是遇到不同大小的 putty 切換畫面時會怪怪的..
00:40 jnlin> chinsan: 我大概習慣當掉以後去重開了XD
00:41 gslin_csie> chinsan: 會當是因為另外一個 terminal 卡住了,給 sshd 一腳就好
00:43 chinsan> gslin_csie: 原來是這樣 @_@, 下次先試試看
00:43 * chinsan 都 -wipe
00:45 kcwu> 原來如此...
00:46 jnlin> gslin_csie: 有時候是 socket 不見了XD
00:46 gslin_csie> jnlin: 那就給他個 USR1?
00:46 gslin_csie> 還是 CONT?
00:47 yinjieh> 現在 socket 不見我都找一個 screen 裡面的 shell kill -9
00:47 yinjieh> 就回來了
00:48 gslin_csie> 都猜錯了,是 SIGCHLD...
00:48 gslin_csie> http://www4.informatik.uni-erlangen.de/~jnweiger/screen-faq.html
00:48 gslin_csie> "For some unknown reason, the fifo in /tmp/screens/S-myname is gone, and i can't resume my screen session. Is there a way to recreate the fifo?"
00:48 KN16H7> hmmm
00:49 jnlin> gslin_csie++
00:49 jnlin> 下次試試XD
00:49 gslin_csie> 我記得很久前本頻道有人講過啊
00:49 gslin_csie> yinjieh: 我記得明明就是你講的
00:50 chinsan> yinjieh: XD
00:50 yinjieh> gslin_csie: 是我找的沒錯啊 XD

Q: For some unknown reason, the fifo in /tmp/screens/S-myname is gone, and i can't resume my screen session. Is there a way to recreate the fifo?
A: Screen checks the fifo/socket whenever it receives a SIGCHLD signal. If missing, the fifo/socket is recreated then. If screen is running non set-uid the user can issue a 'kill -CHLD screenpid' directly (it is -CHILD on some systems). Screenpid is the process-id of the screen process found in a 'ps -x' listing. But usually this won't work, as screen should be installed setuid root. In this case you will not be able to send it a signal, but the kernel will. It does so, whenever a child of screen changes its state. Find the process-id (shellpid below) of the "least important" shell running inside screen. The try 'kill -STOP shellpid'. If the fifo/socket does not reappear, destroy the shell process. You sacrify one shell to save the rest. If nothing works, please do not forget to remove all processes running in the lost screen session.

所以解法就是送 SIGCHLD 給該 screen PID,那麼 screen 就會自動檢查 fifo/socket。比方該 screen PID 為 5566,那麼拯救 screen 的方是就是 kill -s CHLD 5566 或者 kill -20 5566 亦可。

另外,看不太懂上面那段 kill 是要幹嘛的,可以看看 kill(1) 指令有寫:
Some of the more commonly used signals:
1 HUP (hang up)
2 INT (interrupt)
3 QUIT (quit)
6 ABRT (abort)
9 KILL (non-catchable, non-ignorable kill)
14 ALRM (alarm clock)
15 TERM (software termination signal)

sigaction(2)有更詳細的解釋,
SIGCHLD discard signal child status has changed

或者參考 src/sys/sys/signal.h
#define SIGCHLD 20 /* to parent on child stop or exit */

2 comments:

jeffhung said...

用 ctrl-a k (或 ctrl-a :kill,若 ctrl-a k 在 screenrc 裡被關掉了的話),幾乎保證一定會「卡住」。

chinsan said...

XD