В 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
.
/dev/null
, или просто это не tty?{ readlink -f /dev/stdin; } <&6
для случая , когда вы использовали Exec и удалить узел/root/secretunknownname (deleted)
. Как показывает, что файл был удален: Разве этого недостаточно для того, что вам нужно?stat
решение работает только одно./dev/null
, но не обязательно. Вы можете "псевдоним" сmknod
s, иллюстрируется в моем примере.Ответы:
На Linux вы можете сделать это с:
В Linux без stat (1) (например, busybox на вашем маршрутизаторе):
На * BSD:
В системах , такие как * BSD и Solaris,
/dev/stdin
,/dev/fd/0
и/proc/PID/fd/0
не являются «магическими» символьными ссылками как на Linux, но символьные устройства , которые будут переключаться на реальный файл при открытии . Stat (2) на их пути вернет что-то отличное от fstat (2) в дескрипторе открытого файла.Это означает, что пример Linux не будет работать там, даже с установленным GNU coreutils. Если версии GNU stat (1) достаточно недавние, вы можете использовать
-
аргумент, чтобы позволить ему выполнить fstat (2) для файлового дескриптора 0, так же как stat (1) из * bsd:Также очень легко выполнить проверку переносимо на любом языке, который предлагает интерфейс для fstat (2), например. в
perl
:источник
/dev/null
есть1:3
, вы можете проверить это немедленно.stat
команду, я был бы уже вполне удовлетворен. Я не вижу смысла в открытии войны редактирования между`
и$(
сторонников. Лично я предпочитаю,$(...)
и есть некоторые обоснования POSIX в пользу этого синтаксиса ( pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) Но я не вижу смысла в даунтинге, если нет правильного ответа на что-то, не связанное с вопрос.$( ... )
в контексте этого ответа предпочтительнее обратных кавычек?$(..)
гнездах стиля легко и AIUI является POSIX предпочтительного подхода. Я, конечно, не собирался начинать редактирование войны, предпочитая комментировать с предложением, а не менять свой отличный ответ.В Linux, чтобы определить, перенаправлен ли стандартный ввод
/dev/null
, вы можете проверить,/proc/self/fd/0
имеет ли то же устройство и inode, что и/dev/null
:Вы можете использовать
/dev/stdin
вместо/proc/self/fd/0
.Если вы хотите проверить, перенаправлен ли стандартный ввод с нулевого устройства, вам нужно сравнить старшие и младшие номера устройств, например, используя
stat
(см. Также ответ mosvy ):или, если вас не волнует, что это специфично для Linux ,
источник
bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null'
затем сделайте это снова с</dev/null
. +1/dev/stdin
Быть символическим в исходный файл специфичен для Linux, так что все эти решения являются Linux-специфические в любом случае. Дляstat
основанных требуется GNU или busyboxstat
. С недавних версиях GNUstat
, вы можете использовать ,stat -
чтобы сделатьfstat()
на FD 0 , который будет затем работать на системах , отличных от Linux./dev/null
нулевое устройство и устройство.Для проверки того, что stdin - это
null
устройство (открыто/dev/null
или нет (как копия/dev/null
)), сzsh
(чьяstat
встроенная версия предшествует GNU и FreeBSDstat
, кстати (не IRIX ', хотя))):(обратите внимание, что в нем не указано, был ли дескриптор файла открыт в режиме «только чтение», «только запись» или «чтение + запись»).
Чтобы проверить, что он открыт
/dev/null
конкретно/some/chroot/dev/null
для текущего файла (не, например), только в Linux (где/dev/stdin
он реализован в виде символической ссылки на файл, открытый на fd 0 вместо специального устройства, которое при открытии действует как adup(0)
в других системах):На не Linux вы можете попробовать:
источник