Linux

如何從 shell 中檢查 stdin 是否為 /dev/null?

  • November 27, 2018

在 Linux 上,有沒有辦法讓 shell 腳本檢查其標準輸入是否從空設備 (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

我懷疑我“只是”需要讀取輸入設備的 maj/min 數。但是我找不到從外殼中做到這一點的方法。


沒有必要只是/dev/null,但任何*空設備,即使是手動創建的mknod

在 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/0不是 linux 上的“神奇”符號連結,而是在打開時*會切換到真實文件的字元設備。它們路徑上的 stat(2) 將返回與打開的文件描述符上的 fstat(2) 不同的東西。

這意味著即使安裝了 GNU coreutils,linux 範例也無法在那里工作。如果 GNU stat(1) 的版本足夠新,您可以使用-參數讓它對文件描述符 0 執行 fstat(2),就像 *bsd 中的 stat(1):

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])'; }

引用自:https://unix.stackexchange.com/questions/484228