Linux
如何從 shell 中檢查 stdin 是否為 /dev/null?
在 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])'; }