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!


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

  • 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

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:

# ....
( 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).

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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