Skip to main content
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

It is due to some file descriptors still open though the app is stopped. You can list the open file descriptors using the techniques mentioned here.

If you need to close the file descriptors without rebooting, you can follow the approach mentioned by Graeme herehere.However, you need to be aware of the file descriptors that you are closing as highlighted by Graeme in his answer. His answer is,

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

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

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 this some shells also seem to have other file descriptors open by default. In bash you have 255 (also for terminal I/O) and 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
    0|1|2|255)
      ;;
    *)
      eval "exec $fd>&-"
      ;;
  esac
done

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

###Update

For further information on the portability of /proc/$$/fd, please see Portability of file descriptor linksPortability 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-).

It is due to some file descriptors still open though the app is stopped. You can list the open file descriptors using the techniques mentioned here.

If you need to close the file descriptors without rebooting, you can follow the approach mentioned by Graeme here.However, you need to be aware of the file descriptors that you are closing as highlighted by Graeme in his answer. His answer is,

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

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

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 this some shells also seem to have other file descriptors open by default. In bash you have 255 (also for terminal I/O) and 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
    0|1|2|255)
      ;;
    *)
      eval "exec $fd>&-"
      ;;
  esac
done

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

###Update

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

It is due to some file descriptors still open though the app is stopped. You can list the open file descriptors using the techniques mentioned here.

If you need to close the file descriptors without rebooting, you can follow the approach mentioned by Graeme here.However, you need to be aware of the file descriptors that you are closing as highlighted by Graeme in his answer. His answer is,

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

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

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 this some shells also seem to have other file descriptors open by default. In bash you have 255 (also for terminal I/O) and 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
    0|1|2|255)
      ;;
    *)
      eval "exec $fd>&-"
      ;;
  esac
done

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

###Update

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

Source Link
Ramesh
  • 40.6k
  • 44
  • 149
  • 222

It is due to some file descriptors still open though the app is stopped. You can list the open file descriptors using the techniques mentioned here.

If you need to close the file descriptors without rebooting, you can follow the approach mentioned by Graeme here.However, you need to be aware of the file descriptors that you are closing as highlighted by Graeme in his answer. His answer is,

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

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

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 this some shells also seem to have other file descriptors open by default. In bash you have 255 (also for terminal I/O) and 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
    0|1|2|255)
      ;;
    *)
      eval "exec $fd>&-"
      ;;
  esac
done

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

###Update

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