さまざまなシェルのfd数が固定されていますか?

さまざまなシェルのfd数が固定されていますか?

仮定:

xb@dnxb:/tmp$ echo 'ls -l /proc/$$/fd | grep a.sh' > a.sh; \
> while IFS='' read -r f; do \
> echo "$f"; "$f" a.sh; \
> done < <(tail -n +2 /etc/shells)
/bin/sh
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 10 -> /tmp/a.sh
/bin/dash
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 10 -> /tmp/a.sh
/bin/bash
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 255 -> /tmp/a.sh
/bin/rbash
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 255 -> /tmp/a.sh
/bin/zsh
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 11 -> /tmp/a.sh
/usr/bin/zsh
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 11 -> /tmp/a.sh
/bin/ksh93
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 10 -> /tmp/a.sh
/bin/rksh93
lr-x------ 1 xiaobai xiaobai 64 Jan  20 00:09 10 -> /tmp/a.sh
xb@dnxb:/tmp$ 

デフォルトでは、bashは常にfd番号255を変更し、zshはfd番号11を変更しますか?

シェルプロセスで実行されているフルパスを抽出する必要があるため、この質問をします。この固定番号を引用または引用しないようにスクリプトをハードコードできるかどうか疑問に思います。

これはプライベートスクリプト用であり、ビジネスにとって重要な基盤として実行することを意図したものではないため、100%信頼できるスクリプトを探していません。ほとんどの場合、fd番号は固定されていますか?

[修正する]:

分析しない理由はcmdline次のとおりです。

xb@dnxb:~/Downloads$ cat foo.sh 
#!/bin/bash
cat "/proc/$$/cmdline" | tr '\0' '\n'
readlink -f /proc/$$/fd/255

xb@dnxb:~/Downloads$ bash --norc foo.sh --norc
bash
--norc
foo.sh
--norc
/home/xiaobai/Downloads/foo.sh
xb@dnxb:~/Downloads$ 

ご覧のとおり、fdフルパスのみを提供できますが、/home/xiaobai/Downloads/foo.sh提供できませんcmdline。スクリプトは、起動しないかのように醜いチェックを実行しない限り、すべてのオプションの場所に表示される可能性があるパスやオプションを区別することはできfoo.shません。 。--norcfoo.sh--

fdこれにより、問題なく正しいフルパスが生成されますbash --norc foo.sh --norc foo2.sh

とにかく、私はカスタムプロセス以外のシステムプロセスがシェルから継承されていないことがわかったので、私の仕事でこれを確認する必要はないことに気づきました。しかし、どんな答えでも、将来の読者にはまだ役立つでしょう。

ベストアンサー1

あなたが確信できる唯一のことはfds 1から9ではないということです。これは、POSIX sh実装でユーザーの使用のために予約されており、sh < your-scriptこの場合は0を使用できるためです。 yashはこれをfds 1から99に拡張します。

起動時にそのfdが開いている場合、シェルは異なる値を使用するため、固定値として信頼できません。ほとんどのシェルは、内部fdとして9(yashの場合は99)以上の最初の自由fdを使用しているようです。bash255を使用して使用できない場合は、上がるのではなく降りているようです。

bash-5.0$ bash a 255> /dev/null
total 0
lrwx------ 1 chazelas chazelas 64 Sep 26 18:03 0 -> /dev/pts/12
lrwx------ 1 chazelas chazelas 64 Sep 26 18:03 1 -> /dev/pts/12
lrwx------ 1 chazelas chazelas 64 Sep 26 18:03 2 -> /dev/pts/12
lr-x------ 1 chazelas chazelas 64 Sep 26 18:03 254 -> /home/chazelas/a
l-wx------ 1 chazelas chazelas 64 Sep 26 18:03 255 -> /dev/null
bash-5.0$ ulimit -n 123
bash-5.0$ bash a
total 0
lrwx------ 1 chazelas chazelas 64 Sep 26 18:03 0 -> /dev/pts/12
lrwx------ 1 chazelas chazelas 64 Sep 26 18:03 1 -> /dev/pts/12
lr-x------ 1 chazelas chazelas 64 Sep 26 18:03 122 -> /home/chazelas/a
lrwx------ 1 chazelas chazelas 64 Sep 26 18:03 2 -> /dev/pts/12

$0通常、実行中のスクリプトのパスインポートを使用するのが最善の方法です。また見なさい:$ 0には常にスクリプトパスが含まれていますか?

おすすめ記事