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.