zshが開いたファイル記述子を1つ減らすのはなぜですか?

zshが開いたファイル記述子を1つ減らすのはなぜですか?

一般的な方法でファイル記述子を明示的に開くことができます。

$ ls -lh /dev/fd/
total 0
lrwx------ 1 tavianator users 64 Jul 10 11:06 0 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:06 1 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:06 2 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:06 3 -> /proc/31288/fd
$ exec 3<foo
$ ls -lh /dev/fd/
total 0
lrwx------ 1 tavianator users 64 Jul 10 11:07 0 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:07 1 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:07 2 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:07 3 -> /home/tavianator/foo
lr-x------ 1 tavianator users 64 Jul 10 11:07 4 -> /proc/31334/fd

今まではそんなに良くなった。 zsh2桁のファイル記述子構文はサポートされていないようですが、10<foo変数置換構文はサポートされています{fd}<foo

$ fd=10
$ exec {fd}<foo
$ ls -lh /dev/fd/
total 0
lrwx------ 1 tavianator users 64 Jul 10 11:08 0 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:08 1 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:08 11 -> /home/tavianator/foo
lrwx------ 1 tavianator users 64 Jul 10 11:08 2 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:08 3 -> /home/tavianator/foo
lr-x------ 1 tavianator users 64 Jul 10 11:08 4 -> /proc/31413/fd

しかし、待って、なぜfdですか?11代わりに開く10

ベストアンサー1

それがZSHが書かれた方法だからです。デフォルトでは、ZSH はファイル記述子を fd 10 にコピーします。

$ PS1='%% ' zsh -f
% lsof -p $$ | grep 10u
zsh     29192 jhqdoe   10u   CHR  136,0       0t0         3 /dev/pts/0
% 

Src/exec.c後続の呼び出しのfd関連コードmovefd

/**/
static void
addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
      char *varid)
{
    int pipes[2];

    if (varid) {
        /* fd will be over 10, don't touch mfds */
        fd1 = movefd(fd2);
        if (fd1 == -1) {
            zerr("cannot moved fd %d: %e", fd2, errno);
            return;

次に、Src/utils.c利用可能な10個以上は既に基本的にとられたものなので、最初に見ることができるのは11個の項目を繰り返します。

movefd(int fd)
{
    if(fd != -1 && fd < 10) {
#ifdef F_DUPFD
        int fe = fcntl(fd, F_DUPFD, 10);
#else
        int fe = movefd(dup(fd));
#endif

私のzsh基準はコードパスをstrace使用していますが、zshはデフォルトでその番号に重複を格納するため、11で始まる新しいfdを使用できないという意見があります。fcntlfcntl(...movefd(dup(...

これ{somelabel}はすべて10より大きい利用可能な最低ファイル記述子を取得することです。これは、シェルが開いている他の項目に応じて、11またはより高い数字である可能性があります。

% exec {foo}>asdf
% echo $foo
11
% exec {quer}>asdf
% echo $quer
12
...

おすすめ記事