bash: / dev / stderr: Permissão negada

18

Após a atualização para uma nova versão, meus scripts bash começam a gerar erros de spitting:

bash: /dev/stderr: Permission denied

em versões anteriores, o Bash iria reconhecer internamente esses nomes de arquivos (é por isso que esta questão não é uma duplicata de este e fazem a coisa certa (tm) , no entanto, isso parou de funcionar agora. O que posso fazer para poder executar meus scripts novamente com êxito?

Eu tentei adicionar o usuário executando o script ao grupo tty , mas isso não faz diferença (mesmo depois de fazer logout e voltar).

Eu posso reproduzir isso na linha de comando sem problema:

$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release

Em um sistema antigo (Ubuntu 10.04):

$ echo $BASH_VERSION
4.1.5(1)-release
    
por 0xC0000022L 13.05.2012 / 06:17

4 respostas

36

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.

    
por 13.05.2012 / 19:54
1

Na verdade, a razão para isso é que o udev define especificamente as permissões para 0620 nos dispositivos tty e o su não altera a propriedade nem as permissões nem deveria. Na minha opinião, isso nos deixa em uma situação que torna / dev / std * não portável.

A solução simples é colocar "mesg y" em / etc / profile (ou qualquer perfil de nível superior que você goste de usar) já que isso muda as permissões do seu dispositivo tty para 0622. Eu realmente não gosto disso, mas provavelmente é melhor que mudar as regras do udev.

    
por 26.02.2013 / 10:49
0

Como usuário do Linux há muito tempo, instalei recentemente um novo sistema LTS do Ubuntu 64 bit 12.04 e fiquei desconcertado sobre o motivo de meus scripts bash não estarem funcionando - permissão negada - e, posteriormente, encontrei este segmento. Eu pensei que o problema pode ser devido a algo no novo sistema operacional.

No final, descobri que usei estupidamente uma ferramenta de interface do usuário para definir permissões no meu diretório /home , e o problema era drive -related. Para ter certeza, criei um diretório temp em /opt e descobri que meus scripts seriam executados bem por lá. Depois de corrigir as permissões da unidade /home , tudo voltou ao normal.

Um pequeno mistério resolvido. suspiro

    
por 22.08.2012 / 23:27
-1

Essa é uma pergunta antiga, mas ainda acho muito relevante, por isso aqui está a solução que encontrei e que não é mencionada aqui.

Me deparei com essa questão, pois também vi problemas em um comando de execução de conta comutada 'su' como esta no bash:

echo test > /dev/stderr

Como tudo o que estou tentando fazer é redirecionar stdout para stderr, o seguinte é o mesmo, e funciona até mesmo em uma conta 'su':

echo test 1>&2
    
por 05.12.2018 / 20:50