Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

so I was wondering why there are some hanging SSH connection left from some of my automated scripts and I came to a weird issue - SSH, if used without PTY, doesn't terminate when the output pipe gets closed. This has already been discussed in several other questions here, but I didn't find an applicable answer - some people adviced to use -t option, but that requests the PTY and piping doesn't work.

Anyway, I reduced the issue to following minimal example:

#this works
cat /dev/zero |false

#this never terminates
ssh user@host "cat /dev/zero" |false

Is there any explanation why would SSH ignore SIGPIPE that rises from writing to already dead pipe (the one that led to false), or any method to make this "work" correctly?

Note that "relaying" the SIGPIPE to the remote host isn't needed - simply killing the ssh client (which is what would exactly happen without ignoring SIGPIPEs) leads to same result with less complexity and some "more correct" assumptions.

Thanks for your ideas!

-mk

EDIT: happens only on Sun_SSH server, looks like some kind of undocumented issue. I'm searching for some good workaround.

share|improve this question
    
What system? ssh localhost 'cat /dev/zero' | false works for me. If the ssh client dies, so does the connection, so does sshd, so does the pipe cat writes to to sshd, so cat should get a SIGPIPE on the remote host as well. So it looks like the problem is with your ssh client not dying of the SIGPIPE. –  Stéphane Chazelas Oct 12 '14 at 11:14
    
whoa, looks like other ssh servers work okay. I was testing it against solaris SSH: Sun_SSH_1.5, SSH protocols 1.5/2.0, OpenSSL 0x1000108f. Gonna ask solaris people. –  exa Oct 12 '14 at 11:19

1 Answer 1

Answering my own question: This is a known issue with Sun SSH. The best workaround I found is to detect "Sun_SSH" in output of ssh -V and apply something like this:

#!/bin/bash
# ....
( ssh host 'localCommand' | remoteCommand || pkill -P $BASHPID )

You may also use $$ instead of $BASHPID in other shells or in simpler situations (if your shell doesn't have any other child processes).

share|improve this answer
    
ITYM (p=$BASHPID; ssh host remoteCommand | { localCommand || pkill -P "$p"; }) –  Stéphane Chazelas Oct 12 '14 at 17:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.