What Does <&- Do in Bash? - IO Redirection Explained

bashio-redirectionshell

I copied a snippet of Bash to background an ssh command executed remotely:

ssh user@remote <<CMD
some process <&- >log 2>error &
CMD

What does <&- do?
My guess is that it is the same as < /dev/null

My next understanding is that the three main file descriptors (stdin, stdout, stderr) need to be closed to prevent:

  1. The job being backgrounded and the script exiting — conflicting
    somehow?
  2. When the terminal closes, all processes that are
    accepting stdin from terminal are closed?

Best Answer

<&- is not quite the same thing as < /dev/null. <&- closes fd 0, whereas < /dev/null redirects it from the device /dev/null, which never provides any data and always gives EOF on read. The difference is mostly that a read(2) call from a closed FD (the <&- case) will error with EBADF, whereas a call from a null-redirected FD will return no bytes read (end-of-file condition). If your program never reads from stdin, the distinction doesn't matter.

Closing the FDs is good practice if you're backgrounding something, since a backgrounded process will hang if it tries to read anything from TTY. This example doesn't fully handle everything it should, though; ideally there would be a nohup or setsid invocation somewhere, to fully disassociate the background process.