| # Builds a " 3>&- 4>&-" string. |
| # Note: one of these fds is a directory opened to /proc/self/fd |
| # for globbing. It is unwanted, but I don't know how to filter it out. |
| find_fds() { |
| fds="" |
| for f in /proc/self/fd/*; do |
| test "$f" = "/proc/self/fd/0" && continue |
| test "$f" = "/proc/self/fd/1" && continue |
| test "$f" = "/proc/self/fd/2" && continue |
| fds="$fds ${f##*/}>&-" |
| done |
| } |
| |
| find_fds |
| fds1="$fds" |
| |
| # One of the fds is open to the script body |
| # Close it while executing something. |
| eval "find_fds $fds" |
| |
| # Shell should not lose that fd. Did it? |
| find_fds |
| test x"$fds1" = x"$fds" \ |
| && { echo "Ok: script fd is not closed"; exit 0; } |
| |
| # One legit way to handle it is to move script fd. For example, if we see that fd 10 moved to fd 11: |
| test x"$fds1" = x" 10>&- 3>&-" && \ |
| test x"$fds" = x" 11>&- 3>&-" \ |
| && { echo "Ok: script fd is not closed"; exit 0; } |
| # or we see that fd 3 moved to fd 10: |
| test x"$fds1" = x" 3>&- 4>&-" && \ |
| test x"$fds" = x" 10>&- 3>&-" \ |
| && { echo "Ok: script fd is not closed"; exit 0; } |
| |
| echo "Bug: script fd is closed" |
| echo "fds1:$fds1" |
| echo "fds2:$fds" |
| exit 1 |