Sous Linux, existe-t-il un moyen pour un script shell de vérifier si son entrée standard est redirigée depuis le périphérique nul (1, 3) * , idéalement sans rien lire?
Le comportement attendu serait:
./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no
EDIT
mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes
Je soupçonne que j'ai "juste" besoin de lire le nombre maj / min du périphérique d' entrée . Mais je ne peux pas trouver un moyen de le faire à partir du shell.
* Pas nécessaire seulement
/dev/null
, mais tout appareil nul même s'il a été créé manuellement avec mknod
.
/dev/null
, ou tout simplement que ce n'est pas un tty?{ readlink -f /dev/stdin; } <&6
pour le cas où vous avez utilisé exec et supprimé le nœud est/root/secretunknownname (deleted)
. Comme cela montre que le fichier a été supprimé: n'est-ce pas suffisant pour ce dont vous avez besoin?stat
solution est la seule qui fonctionne./dev/null
, mais pas nécessaire. Vous pouvez "alias" est avecmknod
s illustré dans mon exemple.Réponses:
Sous linux, vous pouvez le faire avec:
Sur un Linux sans stat (1) (par exemple, la busybox de votre routeur):
Sur * bsd:
Sur les systèmes tels que * bsd et solaris,
/dev/stdin
,/dev/fd/0
et/proc/PID/fd/0
ne sont pas des liens symboliques « magiques » comme sur les périphériques Linux, mais le caractère qui passera au fichier réel lors de l' ouverture . Un stat (2) sur leur chemin retournera quelque chose de différent d'un fstat (2) sur le descripteur de fichier ouvert.Cela signifie que l'exemple Linux ne fonctionnera pas là-bas, même avec les coreutils GNU installés. Si les versions de GNU stat (1) sont assez récentes, vous pouvez utiliser l'
-
argument pour le laisser faire un fstat (2) sur le descripteur de fichier 0, tout comme le stat (1) de * bsd:Il est également très facile de faire la vérification de manière portative dans n'importe quelle langue qui offre une interface à fstat (2), par exemple. dans
perl
:la source
/dev/null
est1:3
, vous pouvez le tester immédiatement.stat
commande, j'aurais déjà été assez satisfait. Je ne vois pas l'intérêt de lancer une guerre d'édition entre`
et$(
partisans. Personnellement, je préfère$(...)
et il y a des raisons POSIX en faveur de cette syntaxe ( pubs.opengroup.org/onlinepubs/9699919799/xrat/… ) Mais je ne vois pas l'intérêt de voter en aval une réponse par ailleurs correcte pour quelque chose qui n'est pas lié à la question.$( ... )
on préfère les raccourcis dans le contexte de cette réponse?$(..)
style s'imbrique plus facilement et AIUI est l'approche préférée de POSIX. Je n'avais certainement pas l'intention de commencer une quelconque forme d'édition de guerre, préférant commenter avec une suggestion plutôt que de changer votre excellente réponse.Sous Linux, pour déterminer si l'entrée standard est redirigée à partir de
/dev/null
, vous pouvez vérifier si/proc/self/fd/0
le même périphérique et le même inode que/dev/null
:Vous pouvez utiliser à la
/dev/stdin
place de/proc/self/fd/0
.Si vous souhaitez vérifier si l'entrée standard est redirigée à partir du périphérique nul, vous devez comparer les numéros de périphérique majeur et mineur, par exemple en utilisant
stat
(voir également la réponse de mosvy ):ou, si vous ne vous souciez pas que ce soit spécifique à Linux ,
la source
bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null'
puis recommencez avec</dev/null
. +1/dev/stdin
être un lien symbolique vers le fichier d'origine est spécifique à Linux, donc toutes ces solutions sont spécifiques à Linux de toute façon. Lesstat
ceux à base exigent GNU ou busyboxstat
. Avec les versions récentes de GNUstat
, vous pouvez utiliserstat -
pour faire unfstat()
sur fd 0 qui fonctionnerait alors sur des systèmes non Linux./dev/null
et le dispositif nul.De manière portative, pour vérifier que stdin est le
null
périphérique (ouvert/dev/null
ou non (comme une copie de/dev/null
)), aveczsh
(dont lastat
version antérieure à GNU et FreeBSD eststat
d'ailleurs (pas IRIX 'cependant))):(notez qu'il ne dit pas si le descripteur de fichier était ouvert en mode lecture seule, écriture seule ou lecture + écriture).
Pour vérifier qu'il est ouvert
/dev/null
spécifiquement sur le fichier actuel (pas/some/chroot/dev/null
par exemple), sur Linux uniquement (où/dev/stdin
est implémenté en tant que lien symbolique vers le fichier ouvert sur fd 0 au lieu d'un périphérique spécial qui, lorsqu'il est ouvert, agit comme undup(0)
dans d'autres systèmes):Sur non-Linux, vous pouvez essayer:
la source