shell 关闭文件描述符 num 19

shell closes file descriptor num 19

调试我的应用程序我发现 shell 解释器(Solaris 上的 /bin/sh,Debian 中的 /bin/dash)的奇怪行为。在 shell 文件描述符中 fork()ing by number 19(dec) 被 shell 关闭。在我的例子中,它导致关闭进程之间的通信套接字对。

查看 shell 来源,我发现了这个 one and this:

为简洁起见:

/* used for input and output of shell */
#define     INIO        19

if (input > 0) {
    Ldup(input, INIO);
    input = INIO;
}

...

static void
Ldup(int fa, int fb)
{
    if (fa >= 0) {
        if (fa != fb) {
            close(fb);
            fcntl(fa, 0, fb); /* normal dup */
            close(fa);
        }
        fcntl(fb, 2, 1);    /* autoclose for fb */
    }
}

所以 netto 只是关闭 FD 号 INIO(19);

复制简单测试:

$ exec 19>&1
$ echo aaa >&19
aaa
$ bash -c 'echo aaa >&19'
aaa
$ dash -c 'echo aaa >&19'
dash: 1: Syntax error: Bad fd number
$ ksh -c 'echo aaa >&19'
aaa

问题是:

19 是特殊的,因为(很久以前),最大打开文件数是 20,例如,

#define _NFILE  20

stdio.h

在POSIX中,您可能会通过sysconf界面看到其他符号,例如OPEN_MAX

  • 文件描述符从 0 开始计数,并且
  • 通常按升序分配
  • 所以 "last possible" 文件描述符应该是 19。
  • 如果有一个未使用的文件描述符,将其设为 last 将 "work".

Solaris sh(特别是从 Solaris 10 开始)和 dash 都有一段时间了,您注意到的细节可能并没有破坏任何遗留的 shell 重要(很多)脚本。