A shell script can lose its standard and other file descriptors if the other end goes away. One way this can happen is by terminating a ssh client used to launch the script:

$ ssh localhost test

This launches a bash script called test over SSH and a CtrlC is used to terminate the ssh command. This does not terminate test which continues running but it does close the attached file descriptors (e.g. standard input/output/error).

If test tries to use those closed file descriptors then it will terminate with a SIGPIPE. A simple echo will suffice.

One of the things test might have is a log function that uses echo to write messages to the systemd journal and also to standard error. Something like this:

log() {
 echo "$*" | systemd-cat -t test
 echo >&2 "$*"

The second echo raises a SIGPIPE after the ssh session is killed (CtrlC). This can be protected against, so that execution continues without the offending echo, by putting the echo in a subshell:

( echo >&2 "$*" )

But is there a better way?

  • 1
    Writing stdout or stderr will SIGPIPE (perhaps not immediately); reading stdin will just EOF. – dave_thompson_085 Nov 15 '16 at 10:28

You could if you want ignore SIGPIPE in the script:

trap "" PIPE
  • true, but I wondererd if there was a way to avoid the signal in the first place, by detecting the closed fd and not calling the command (echo) that would cause the signal. – starfry Nov 14 '16 at 8:44
  • As far as I can see, the only widely-available way to check whether a file descriptor is open in a shell script is to use -t: [[ -t 2 ]] && echo >&2 "$*". This checks whether file descriptor 2 is open and attached to a terminal. Unfortunately this requires the SSH session to have a terminal (ssh -t), which terminates the process with SIGHUP when you press Ctrl+C! You could work around that too but it's probably not worth it. If you don't care about the error messages when the script is run via SSH then it might be acceptable though (with the usual time-of-check-to-time-of-us caveat). – Stephen Kitt Nov 15 '16 at 8:13
  • would trap "exec 2>/dev/null" PIPE works ? – Emmanuel Nov 15 '16 at 10:17

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.