【 以下文字转载自 Java 讨论区 】
发信人: creation (努力自由泳50m/45sec !), 信区: Java
标 题: Re: very archaic issue :
发信站: BBS 未名空间站 (Fri Apr 29 11:58:14 2011, 美东)
one colleague replied
using ssh -t ....
would help
here is my reply to him (his approach partially works, but only when you
terminate ssh client by ctrl-C, which is SIGINT, it does not work
when the ssh is run by a daemon like hudson, and terminated with -15 )
######################################
This is a cleaner way than the hack I came up with: I found that “normally
” the remote code terminates because it wants to print to the terminal,
Which is closed after ssh is closed, so the remote code gets itself a
SIGPIPE. Java somehow carefully avoided the SIGPIPE generation OR ignores
sigpipe,
So it never terminates. My hack was to , as soon as the remote shell starts
, I fire off a sub process to continuously spit out something onto the
STDOUT,
So that this subprocess will be given a sigpipe when ssh closes, and that
subprocess (bash process) traps SIGPIPE and in the sig handler, it sends a
kill to the
Pgid, so that all children of the remote shell are killed, including java.
This is a hard kill with -9
Your “-t” approach does work if I do a “ctrl-C” on the client side,
because ssh behavior is to transport the ctrl-C to remote side, which then
pretty much acts like
A normal tty. But in our particular case, the Hudson job sends a “15” to
kill the Hudson process, so ssh still lingers on.
You can test it with following code a.sh
virtual-machine:~$ cat a.sh
rm /tmp/sig
trap "echo HUP >> /tmp/sig " HUP
trap "echo INT >> /tmp/sig " INT
trap "echo ALRM >> /tmp/sig " ALRM
trap "echo PIPE >> /tmp/sig " PIPE
trap "echo POLL >> /tmp/sig " POLL
trap "echo PROF >> /tmp/sig " PROF
trap "echo TERM >> /tmp/sig " TERM
trap "echo USR >> /tmp/sig " USR
trap "echo USR >> /tmp/sig " USR
trap "echo VTALRM >> /tmp/sig " VTALRM
trap "echo STKFLT >> /tmp/sig " STKFLT
trap "echo PWR >> /tmp/sig " PWR
trap "echo WINCH >> /tmp/sig " WINCH
trap "echo CHLD >> /tmp/sig " CHLD
trap "echo URG >> /tmp/sig " URG
trap "echo TSTP >> /tmp/sig " TSTP
trap "echo TTIN >> /tmp/sig " TTIN
trap "echo TTOU >> /tmp/sig " TTOU
trap "echo STOP >> /tmp/sig " STOP
trap "echo CONT >> /tmp/sig " CONT
trap "echo ABRT >> /tmp/sig " ABRT
trap "echo FPE >> /tmp/sig " FPE
trap "echo ILL >> /tmp/sig " ILL
trap "echo QUIT >> /tmp/sig " QUIT
trap "echo SEGV >> /tmp/sig " SEGV
trap "echo TRAP >> /tmp/sig " TRAP
trap "echo SYS >> /tmp/sig " SYS
trap "echo EMT >> /tmp/sig " EMT
trap "echo BUS >> /tmp/sig " BUS
trap "echo XCPU >> /tmp/sig " XCPU
java -cp .:/tmp/tt.jar TestLog4j
TestLog4j code is a simple dead loop that continuously does Log.info(“
something”)
Run command with
Ssh localhost ‘./a.sh’
Then on the client side, kill the ssh process by “kill -15 your_ssh_pid “,
but the remote bash and java is still running
The funny thing that I don’t understand now is, in the above test, after I
killed the ssh client, I DON’T see the /tmp/sig being generated,
But after I manually kill the java process, and the remote bash terminates,
I can see /tmp/sig being generated, containing the content:
HUP
CONT
This confirms my understanding that a terminated ssh –t would give the
remote side a HUP, but why is the signal cached so long ??? and why is there
a CONT ???
Or does the HUP have nothing to do with ssh ? maybe when the remote bash
terminates, it wants to use the terminal, and only now does it gets a HUP
from the OS ???