从bash启动进程而不继承文件描述符

时间:2014-04-16 09:06:52

标签: linux bash shell

我想从我的bash脚本开始一个新进程,它不会继承父文件描述符。我无法改变这些文件描述符的创建方式。

使用案例 应用程序中的错误 - >错误钩子 - >杀死进程并重新启动它

Windows start without inheritance of parents file descriptors也有类似的主题,但它对Linux不起作用。

这在shell中是否可行?

由于

更新

我知道我可以自己关闭这些描述符我只是想确保不可能通过一些魔术选项启动子项来跳过文件描述符的复制。 (因为这个选项对我来说听起来很合理)

2 个答案:

答案 0 :(得分:5)

通常无法阻止文件描述符继承。在C中你可以使用FD_CLOEXEC,但即使这只是解释here的部分解决方案。

关闭那些你不需要的文件描述符:

exec 3>&- #close fd 3.

更长的例子:

#! /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

答案 1 :(得分:0)

您可以编写一个函数来关闭Bash的10个可继承文件描述符:

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

然后你可以调用fdcloexec your command here来执行命令而不继承文件描述符。