Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a way to close all the open file descriptors, without having an explicit list of them beforehand?

share|improve this question
All of which file descriptors? Every process has some open. – Warren Young Apr 6 '14 at 17:54
up vote 7 down vote accepted

To answer literally, to close all open file descriptors for bash:

for fd in $(ls /proc/$$/fd); do
  eval "exec $fd>&-"

However this really isn't a good idea since it will close the basic file descriptors the shell needs for input and output. If you do this, none of the programs you run will have their output displayed on the terminal (unless they write to the tty device directly). If fact in my tests closing stdin (exec 0>&-) just causes an interactive shell to exit.

What you may actually be looking to do is rather to close all file descriptors that are not part of the shell's basic operation. These are 0 for stdin, 1 for stdout and 2 for stderr. On top of this some shells also seem to have other file descriptors open by default. In bash, for example, you have 255 (also for terminal I/O) and in dash I have 10, which points to /dev/tty rather than the specific tty/pts device the terminal is using. To close everything apart from 0, 1, 2 and 255 in bash:

for fd in $(ls /proc/$$/fd); do
  case "$fd" in
      eval "exec $fd>&-"

Note also that eval is required when redirecting the file descriptor contained in a variable, if not bash will expand the variable but consider it part of the command (in this case it would try to exec the command 0 or 1 or whichever file descriptor you are trying to close).

NOTE: Also using a glob instead of ls (eg /proc/$$/fd/*) seems to open an extra file descriptor for the glob, so ls seems the best solution here.


For further information on the portability of /proc/$$/fd, please see Portability of file descriptor links. If /proc/$$/fd is unavailable, then a drop in replacement for the $(ls /proc/$$/fd), using lsof (if that is available) would be $(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-).

share|improve this answer
/proc is only available under Linux. – chepner Apr 7 '14 at 19:30
@chepner you would be right if you said that /proc/PID/fd is not very portable. But saying that /proc is only available under Linux is not a correct statement. – Graeme Apr 7 '14 at 19:35
Some websites use the <&- form, is it any different/needed? – Lorenzo Pistone Apr 7 '14 at 21:56
@LorenzoPistone, the direction makes no difference when closing a descriptor, so either form can be used. – Graeme Apr 7 '14 at 22:03

In recent versions of Bash (4.1 and onward, year 2009 and later) you can specify the file descriptor to close using a shell variable:

for fd in $(ls /proc/$$/fd/); do
    [ $fd -gt 2 ] && exec {fd}<&-

The feature had been in Korn shell already (since 1993?) but apparently took some time to make its way into Bash.

share|improve this answer

No. The kernel can close only one FD at a time, and bash does not have "group commands" for FDs.

for fd in $(ls -1 /proc/27343/fd); do echo exec "$fd>&-"; done

Remove the echo after testing.

If this is not for the shell itself but for a command to be run then you can use nohup.

share|improve this answer
The file descriptor used by >&- cannot be a parameter; the redirection is parsed prior to parameter expansion. – chepner Apr 7 '14 at 19:35

Your Answer


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.