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. É suisso 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 usernameefetuar login. Quando você sudo su username2, a propriedade de /dev/pts/1não é alterada e username2nã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 hellofunciona mas echo hello > /dev/stdoutfalha.
Uma solução alternativa seria tornar username2um membro do grupo tty, mas isso daria username2permissão para gravar em qualquer tty, o que provavelmente é indesejável.
Outra solução alternativa seria fazer login na username2conta em vez de usar su, de modo que /dev/stdoutaponte 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/stdoute /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/stdoute /dev/stderrseja 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/stdoutet al sejam tratados especialmente se os arquivos existem ou não. O recurso foi introduzido no bash 2.04, e o NEWSarquivo 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_STDINestiver definido (isso é determinado quando o bash é criado a partir da fonte).
Até onde eu sei, nenhuma versão lançada do bash tornou /dev/stdoutincondicional 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.cpara 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/stdoute /dev/stderrcorretamente. 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/stdoute /dev/stderrfuncionou corretamente. Esse problema só aparece quando você suusa 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/stderrels -lL /dev/stdout /dev/stderr?