Eu não acho que isso seja inteiramente uma questão bash.
Em um comentário, você disse que viu esse erro depois de fazer
sudo su username2
quando logado como username . É o su que está provocando 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, é de propriedade de, e gravável por, username ; essa propriedade foi concedida quando username efetuou login. Quando você sudo su username2 , a propriedade de /dev/pts/1 não muda e username2 não tem permissão de gravação.
Eu diria que isso é um bug. /dev/stdout deve ser, na verdade, 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 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 seria entrar na conta username2 em vez de usar su , de modo que /dev/stdout aponte para um pseudoterminal recém-alocado de propriedade de username2 . Isso pode não ser prático.
Outra solução seria modificar seus scripts para que eles não se refiram a /dev/stdout e /dev/stderr ; por exemplo, substitua isso:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
por isso:
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 bash ( info bash ) no meu sistema diga que /dev/stdout e /dev/stderr são tratados especialmente quando usados 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. (POSIX não menciona /dev/std{in,out,err} , então pode ser difícil argumentar que isso é um bug.)
Olhando versões antigas do bash, a documentação implica que /dev/stdout et al são tratados especialmente se os arquivos existem ou não. O recurso foi introduzido no bash 2.04, e o arquivo NEWS para essa versão diz:
The redirection code now handles several filenames specially: /dev/fd/N, /dev/stdin, /dev/stdout, and /dev/stderr, whether or not they are present in the file system.
Mas se você examinar o código-fonte ( redir.c ), verá que essa manipulação especial é ativada somente se o símbolo HAVE_DEV_STDIN for definido (isso é determinado quando o bash é construído da fonte).
Tanto quanto eu posso dizer, não versão lançada do bash tornou a manipulação especial de /dev/stdout et al incondicional - a menos que alguma distribuição tenha corrigido isso.
Então, outra solução alternativa (que eu não tentei) seria pegar as fontes do bash , modificar redir.c para tornar a manipulação especial de /dev/* incondicional e use sua versão reconstruída em vez daquela que acompanha seu sistema. Isso provavelmente é um exagero, no entanto.
RESUMO:
Seu sistema operacional, como o meu, não está lidando corretamente com a propriedade e as permissões de /dev/stdout e /dev/stderr . O bash supostamente trata esses nomes especialmente em redirecionamentos, mas na verdade só o faz se os arquivos não existirem. Isso não importaria se /dev/stdout e /dev/stderr funcionassem corretamente. Esse problema só aparece quando você su para outra conta ou faz algo semelhante; Se você simplesmente acessar uma conta, as permissões estão corretas.