シェルでstdinが/dev/nullであるかどうかを確認するには?

シェルでstdinが/dev/nullであるかどうかを確認するには?

Linuxでは、理想的に何も読み取らず、標準入力が空のデバイス(1、3)*でリダイレクトされていることをシェルスクリプトで確認する方法はありますか?

予想される動作は次のとおりです。

./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no

EDIT

mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes

私は「ただ」入力の最大/最小数を読む必要があると思います。装備。ただし、シェルでこれを行う方法が見つかりません。


*必ずしも必須ではありませんが/dev/nullどの手動で作成してもデバイスは空ですmknod

答え1

Linuxでは、次のことができます。

stdin_is_dev_null(){ test "`stat -Lc %t:%T /dev/stdin`" = "`stat -Lc %t:%T /dev/null`"; }

stat(1) を持たない Linux (例: ルータの busybox):

stdin_is_dev_null(){ ls -Ll /proc/self/fd/0 | grep -q ' 1,  *3 '; }

*bsdから:

stdin_is_dev_null(){ test "`stat -f %Z`" = "`stat -Lf %Z /dev/null`"; }

* bsdやSolarisなどのシステムでは、/dev/stdinおよび/dev/fd/0/proc/PID/fd/0Linuxのような「魔法の」シンボリックリンクではなく、実際のファイルに変換される文字デバイスです。開いたとき。そのパスの stat(2) は、開かれたファイル記述子で fstat(2) と異なるものを返します。

これは、GNU coreutilsがインストールされていてもLinuxの例が機能しないことを意味します。 GNU stat(1) が十分に新しい場合は、-*bsd の stat(1) のように引数を使用して、ファイル記述子 0 で fstat(2) を実行させることができます。

stdin_is_dev_null(){ test "`stat -Lc %t:%T -`" = "`stat -Lc %t:%T /dev/null`"; }

確認も簡単持ち運べるたとえば、fstat(2) インタフェースを提供するすべての言語。存在するperl

stdin_is_dev_null(){ perl -e 'exit((stat STDIN)[6]!=(stat "/dev/null")[6])'; }

答え2

Linuxでは、標準入力がからリダイレクトされていることを確認するには、次のようなデバイスとinodeがあることを/dev/null確認します。/proc/self/fd/0/dev/null

if [ /proc/self/fd/0 -ef /dev/null ]; then echo yes; else echo no; fi

/dev/stdin代わりに使用できます/proc/self/fd/0

標準入力がヌルデバイスからリダイレクトされていることを確認するには、メジャーデバイス番号とマイナーデバイス番号を比較する必要がありますstatMosviの答え):

if [ "$(stat -Lc %t:%T /dev/stdin)" = "$(stat -Lc %t:%T /dev/null)" ]; then echo yes; else echo no; fi

またはこの存在に興味がない場合Linuxのみ

if [ "$(stat -Lc %t:%T /dev/stdin)" = "1:3" ]; then echo yes; else echo no; fi

答え3

null移植可能に、stdinがデバイスのコピーであるか(open/dev/nullかどうか/dev/null)確認するには、次のようにしますzshstatちなみに、組み込み機能はGNUおよびFreeBSDよりも優先されますstat(IRIXではありません))。

zmodload zsh/stat
if [ "$(stat +rdev -f 0)" = "$(stat +rdev /dev/null)" ]; then
  echo stdin is open on the null device
fi

(ファイル記述子が読み取り専用、書き込み専用、または読み取り+書き込みモードで開くかどうかはわかりません。)

/dev/null現在のファイルで開かれているかどうかを確認するには、/some/chroot/dev/nullLinuxでのみ(/dev/stdin他のシステムで開くときに特別なデバイスではなく、fd 0で開かれたファイルへのシンボリックリンクとして実装されますdup(0))、次の手順を実行します。

if [ /dev/stdin -ef /dev/null ]; then
  echo stdin is open on /dev/null
fi

Linuxでない場合は、次のことを試すことができます。

if sh -c 'lsof -tad0 -p"$$" /dev/null' > /dev/null 2>&-; then
  echo stdin is open on /dev/null
fi

関連情報