Eu não acho que isso seja inteiramente um problema de festa.
Em um comentário, você disse que viu esse erro depois de fazer
sudo su username2
quando logado como username
. É su
isso que está desencadeando o problema.
/dev/stdout
é um link simbólico para /proc/self/fd/1
, que é um link simbólico para, por exemplo /dev/pts/1
,. /dev/pts/1
, que é um pseudoterminal, pertence e é gravável por username
; essa propriedade foi concedida ao username
efetuar login. Quando você sudo su username2
, a propriedade de /dev/pts/1
não é alterada e username2
não tem permissão de gravação.
Eu diria que isso é um bug. /dev/stdout
deve ser, com efeito, um alias para o fluxo de saída padrão, mas aqui vemos uma situação em que echo hello
funciona mas echo hello > /dev/stdout
falha.
Uma solução alternativa seria tornar username2
um membro do grupo tty
, mas isso daria username2
permissão para gravar em qualquer tty, o que provavelmente é indesejável.
Outra solução alternativa seria fazer login na username2
conta em vez de usar su
, de modo que /dev/stdout
aponte para um pseudoterminal recém-alocado pertencente a username2
. Isso pode não ser prático.
Outra solução alternativa seria modificar seus scripts para que eles não se refiram /dev/stdout
e /dev/stderr
; por exemplo, substitua isto:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
por este:
echo OUT
echo ERR 1>&2
Eu vejo isso no meu próprio sistema, Ubuntu 12.04, com o bash 4.2.24 - mesmo que o documento do bash ( info bash
) no meu sistema diga isso /dev/stdout
e /dev/stderr
seja tratado especialmente quando usado em redirecionamentos. Mas mesmo que o bash não trate esses nomes especialmente, eles ainda devem atuar como equivalentes para os fluxos de E / S padrão. (O POSIX não menciona /dev/std{in,out,err}
, portanto, pode ser difícil argumentar que isso é um bug.)
Observando versões antigas do bash, a documentação implica que /dev/stdout
et al sejam tratados especialmente se os arquivos existem ou não. O recurso foi introduzido no bash 2.04, e o NEWS
arquivo para essa versão diz:
O código de redirecionamento agora lida com vários nomes de arquivos especialmente: / dev / fd / N, / dev / stdin, / dev / stdout e / dev / stderr, estejam eles presentes ou não no sistema de arquivos.
Mas se você examinar o código fonte ( redir.c
), verá que esse tratamento especial será ativado apenas se o símbolo HAVE_DEV_STDIN
estiver definido (isso é determinado quando o bash é criado a partir da fonte).
Até onde eu sei, nenhuma versão lançada do bash tornou /dev/stdout
incondicional o tratamento especial de et al - a menos que alguma distribuição o tenha corrigido.
Portanto, outra solução alternativa (que eu não tentei) seria pegar as fontes do bash , modificar redir.c
para tornar o /dev/*
tratamento especial incondicional e usar sua versão reconstruída em vez da versão que acompanha o seu sistema. Isso provavelmente é um exagero, no entanto.
RESUMO:
Seu sistema operacional, como o meu, não está lidando com a propriedade e as permissões de /dev/stdout
e /dev/stderr
corretamente. O bash supostamente trata esses nomes especialmente em redirecionamentos, mas na verdade o faz apenas se os arquivos não existirem. Isso não importa se /dev/stdout
e /dev/stderr
funcionou corretamente. Esse problema só aparece quando você su
usa outra conta ou faz algo semelhante; se você simplesmente fizer login em uma conta, as permissões estão corretas.
ls -l /dev/stdout /dev/stderr
els -lL /dev/stdout /dev/stderr
?