Ocasionalmente eu preciso especificar um "caminho-equivalente" de um dos IO padrão córregos ( stdin
, stdout
, stderr
). Desde 99% do tempo em que trabalho com Linux, prefiro /dev/
obter /dev/stdin
, etc., e isso " parece fazer a coisa certa". Mas, por um lado, sempre me senti desconfortável com essa justificativa (porque, é claro, "parece funcionar" até que não funcione). Além disso, não tenho bom senso de quão portátil é essa manobra.
Então, eu tenho algumas perguntas:
No contexto do Linux, é seguro (sim / não) a igualar
stdin
,stdout
estderr
com/dev/stdin
,/dev/stdout
e/dev/stderr
?De maneira mais geral, essa equivalência é "adequadamente portátil "?
Não encontrei nenhuma referência POSIX.
Respostas:
Está disponível no Linux de volta à sua pré-história. É não POSIX, embora muitas conchas reais (incluindo a AT & T
ksh
ebash
) irá simular-lo se ele não está presente no sistema operacional; note que esta simulação só funciona no nível do shell (isto é, parâmetro de redirecionamento ou linha de comando, não como argumento explícito, por exemploopen()
). Dito isto, ele deve estar disponível na maioria dos sistemas Unix comerciais, de uma maneira ou de outra (às vezes é escrito/dev/fd/N
para vários números inteirosN
, mas a maioria dos sistemas com isso fornecerá links simbólicos como o Linux e o * BSD).fonte
/dev/std{in,out,err}
são especificamente listados como não parte do padrão POSIX.1-2008 .ash
não suporta/dev/stdout
em initrd ( git.razvi.ro/... )os
/dev/std{in,out,err}
arquivos normalmente são apenas links simbólicos para/proc/self/fd/{0,1,2}
(respectivamente). Como tal, nada se ganha com o uso de métodos definidos pelo POSIX.Se você deseja ser compatível com POSIX, a melhor maneira de fazer isso é usar o redirecionamento de saída. O redirecionamento de saída do shell é definido no padrão POSIX . Além disso, os números dos descritores de arquivo STDIN, STDOUT, STDERR também fazem parte do POSIX .
Em suma, coisas como
>&2
são garantidas para o trabalho.Uma coisa importante a ser observada, porém, é que o uso de STDIN, STDOUT e STDERR é subjetivo ao modo como o programa foi iniciado. Se o programa foi iniciado com o descritor de arquivo 1 como um identificador aberto para um arquivo, seu programa apenas precisa aceitá-lo. Mesmo se você abrisse o programa
/dev/stdout
, tudo o que faria seria abrir o descritor de arquivo 1, que ainda apontará para esse arquivo.Se é isso que você está tentando contornar, é necessário abrir o TTY diretamente. Normalmente, sem nenhum redirecionamento, STDIN, STDOUT e STDERR são apenas descritores de arquivos abertos, apontando para o mesmo TTY. Não há absolutamente nada além disso.
fonte
/proc/self/fd/1
ou/dev/fd/1
faz parte do POSIX?/dev/std???
são apenas links simbólicos/proc/self/fd
no Linux.O POSIX 7 diz que são extensões.
Definições básicas , Seção 2.1.1 Requisitos:
Encontrado ao grepping o HTML do POSIX: Onde está a lista das funções da API do POSIX C?
Estranhamente, a
uuencode
ferramenta fornece/dev/stdout
um efeito mágico :A documentação do kernel Linux diz que todos os sistemas devem ter.
https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.rst
No entanto, não consegui encontrar onde esses links simbólicos são criados no kernel (distribuição fornecida?).
fonte
/ dev / {stdout, stdin, stderr} trabalha no Bash nestas plataformas:
Mas falha no csh nestes:
fonte
bash
é especial, pois ele pode ser compilado para identificador/dev/fd/x
por si só para redirecionamentos em sistemas que não possuem/dev/fd
Um problema com os
/dev/stdout
amigos é que você pode não ter permissão para escrever neles em determinadas circunstâncias. Por exemplo, encontrei isso ao invocar scripts do Nix e imagino ferramentas semelhantes que executam scripts em cadeias / caixas de areia / contêineres / VMs / etc. pode encontrar problemas semelhantes.Usando a sintaxe como
1>&2
trabalhava nesses casos e, como eu sabia que estaria rodando no Bash, eu poderia usar a substituição de processo por comandos que esperam nomes de arquivos.fonte