4

I want to start a new process from my bash script which won't inherit parent file descriptors. I can't change the way these file descriptors are created.

Use case: error in application -> error hook -> kill the process and restart it

There is a similar topic for windows start without inheritance of parents file descriptors but it doesn't work for Linux.

Is this even possible in shell?

Thanks

UPDATE

I know that I can close those descriptors myself I just want to make sure that it isn't possible to start child with some magic option to skip copying of file descriptors. (because this option sounds reasonable to me)

Community
  • 1
  • 1
jakub.petr
  • 2,951
  • 2
  • 23
  • 34

2 Answers2

7

It is not possible to prevent file descriptor inheritance in general. In C you can use FD_CLOEXEC but even that is only a partial solution as explained here.

Close those file descriptors you do not need:

exec 3>&- #close fd 3.

A longer example:

#! /bin/bash

# Open some file descriptors
for n in $(seq 10 20) ; do
    eval "exec $n>/dev/null"
done

# List them
echo -n "$BASHPID: " ; ls -v /proc/$BASHPID/fd

# Start a sub process without them
(
    # List inherited descriptors
    echo -n "$BASHPID: " ; ls -v /proc/$BASHPID/fd

    # Close all but stdio
    SELF=$BASHPID
    FDS=$(find /proc/$SELF/fd -type l -printf '%f\n')
    # The following will even try to close the fd for the find sub
    # shell although it is already closed. (0: stdin, 1: stdout, 2:
    # stderr, 3: find)
    echo -n 'Closing:'
    for n in $FDS ; do
    if ((n > 2)) ; then
        echo -n " $n"
        eval "exec $n>&-"
    fi
    done
    echo

    # List remaining
    echo -n "$BASHPID: " ; ls -v /proc/$BASHPID/fd

    # Do what you want
)

# Original shell has sill all descriptors
echo -n "$BASHPID: " ; ls -v /proc/$BASHPID/fd
Community
  • 1
  • 1
ceving
  • 21,900
  • 13
  • 104
  • 178
0

You can write a function to close each of Bash's 10 inheritable file descriptors:

fdcloexec () {
  "$@" 0>&- 1>&- 2>&- 3>&- 4>&- 5>&- 6>&- 7>&- 8>&- 9>&-
}

Then you would call fdcloexec your command here to execute your command without inheriting file descriptors.

Stuart P. Bentley
  • 10,195
  • 10
  • 55
  • 84
  • 1
    Other descriptors (e.g. 13) are also inherited, for example into subshell `... | { ... subshell here ... }`. At least in my bash. – Piotr Findeisen Apr 06 '16 at 13:52