No Linux, existe uma maneira de um script de shell verificar se sua entrada padrão é redirecionada do dispositivo nulo (1, 3) * , idealmente sem ler nada?
O comportamento esperado seria:
./checkstdinnull
-> no
./checkstdinnull < /dev/null
-> yes
echo -n | ./checkstdinnull
-> no
EDIT
mknod secretunknownname c 1 3
exec 6<secretunknownname
rm secretunknownname
./checkstdinnull <&6
-> yes
Eu suspeito que "apenas" preciso ler o número principal / min do dispositivo de entrada . Mas não consigo encontrar uma maneira de fazer isso a partir do shell.
* Não é necessário apenas
/dev/null
, mas qualquer dispositivo nulo, mesmo se criado manualmente com mknod
.
/dev/null
ou apenas não é um tty?{ readlink -f /dev/stdin; } <&6
para o caso em que você usou exec e removeu o nó é/root/secretunknownname (deleted)
. Como mostra que o arquivo foi excluído: não é suficiente para o que você precisa?stat
solução é a única que funciona./dev/null
, mas não necessário. Você pode "alias" é commknod
s ilustrado no meu exemplo.Respostas:
No linux, você pode fazer isso com:
Em um Linux sem stat (1) (por exemplo, o busybox no seu roteador):
Em * bsd:
Em sistemas como o * BSD e Solaris,
/dev/stdin
,/dev/fd/0
e/proc/PID/fd/0
não são "mágicas" links simbólicos como em Linux, mas dispositivos de caracteres que irá mudar para o arquivo verdadeiro quando aberto . Um stat (2) no caminho retornará algo diferente de um fstat (2) no descritor de arquivo aberto.Isso significa que o exemplo do linux não funcionará lá, mesmo com o GNU coreutils instalado. Se as versões do GNU stat (1) forem recentes o suficiente, você poderá usar o
-
argumento para fazer um fstat (2) no descritor de arquivo 0, assim como o stat (1) de * bsd:É também muito fácil de fazer o check portably em qualquer idioma que oferece uma interface para fstat (2), por exemplo. em
perl
:fonte
/dev/null
é1:3
, você pode testar para isso imediatamente.stat
comando, eu já estaria bastante satisfeito. Não vejo sentido em iniciar uma guerra de edição entre`
e$(
apoiadores. Pessoalmente, prefiro$(...)
e existem algumas justificativas do POSIX em favor dessa sintaxe ( pubs.opengroup.org/onlinepubs/9699919799/xrat/… ). questão.$( ... )
é preferível a backticks no contexto desta resposta?$(..)
estilo é mais fácil e o AIUI é a abordagem preferida do POSIX. Eu certamente não pretendia iniciar nenhuma forma de guerra de edição, preferindo comentar com uma sugestão do que alterar sua excelente resposta.No Linux, para determinar se a entrada padrão é redirecionada
/dev/null
, você pode verificar se/proc/self/fd/0
possui o mesmo dispositivo e inode que/dev/null
:Você pode usar em
/dev/stdin
vez de/proc/self/fd/0
.Se você deseja verificar se a entrada padrão é redirecionada do dispositivo nulo, é necessário comparar os números principais e secundários do dispositivo, por exemplo, usando
stat
(consulte também a resposta de mosvy ):ou, se você não se importa que isso seja específico do Linux ,
fonte
bash -c 'ls -l /proc/self/fd/0 /dev/null; [[ /proc/self/fd/0 -ef /dev/null ]] && echo dev null'
então faça isso novamente com</dev/null
. 1)/dev/stdin
ser um link simbólico para o arquivo original é específico do Linux; portanto, todas essas soluções são específicas do Linux. Osstat
baseados requerem GNU ou busyboxstat
. Com versões recentes do GNUstat
, você pode usarstat -
para fazer umfstat()
em fd 0, que passaria a trabalhar em sistemas não-Linux./dev/null
e o dispositivo nulo.Portably, para verificar se stdin é o
null
dispositivo (aberto/dev/null
ou não (como uma cópia de/dev/null
)), withzsh
(cujostat
built-in é anterior ao GNU e ao FreeBSDstat
a propósito (embora não seja o IRIX))):(observe que ele não diz se o descritor de arquivo foi aberto no modo somente leitura, somente gravação ou modo leitura + gravação).
Para verificar se ele está aberto
/dev/null
especificamente no arquivo atual (não/some/chroot/dev/null
por exemplo), apenas no Linux (onde/dev/stdin
é implementado como um link simbólico para o arquivo aberto no fd 0, em vez de um dispositivo especial que, quando aberto, atua como umdup(0)
em outros sistemas):No não Linux, você pode tentar:
fonte