Após a atualização para uma nova versão, meus bash
scripts começam a cuspir erros:
bash: /dev/stderr: Permission denied
nas versões anteriores Bash iria reconhecer internamente esses nomes de arquivo (que é por isso que esta questão não é uma duplicata de um presente ) e fazer a coisa certa (tm) , no entanto, isso parou de funcionar agora. O que posso fazer para poder executar meus scripts novamente com sucesso?
Tentei adicionar o usuário executando o script ao grupo tty
, mas isso não faz diferença (mesmo após o logout e o login novamente).
Eu posso reproduzir isso na linha de comando sem problemas:
$ 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 mais antigo (Ubuntu 10.04):
$ echo $BASH_VERSION
4.1.5(1)-release
bash
permissions
stdout
0xC0000022L
fonte
fonte
ls -l /dev/stdout /dev/stderr
els -lL /dev/stdout /dev/stderr
?sudo su username2 -
...echo $BASH_VERSION
Respostas:
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
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 porusername
; essa propriedade foi concedida aousername
efetuar login. Quando vocêsudo su username2
, a propriedade de/dev/pts/1
não é alterada eusername2
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 queecho hello
funciona masecho hello > /dev/stdout
falha.Uma solução alternativa seria tornar
username2
um membro do grupotty
, mas isso dariausername2
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 usarsu
, de modo que/dev/stdout
aponte para um pseudoterminal recém-alocado pertencente ausername2
. 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:por este:
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 oNEWS
arquivo para essa versão diz:Mas se você examinar o código fonte (
redir.c
), verá que esse tratamento especial será ativado apenas se o símboloHAVE_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.fonte
pam_ck_connector.so
./proc/self/fd/1
as permissões estão atualizadas, mas isso não faz sentido, pois é um link simbólico. Também acontece no Fedora, que parece descartar o ConsoleKit.Na verdade, a razão disso é que o udev define especificamente as permissões para 0620 em dispositivos tty e su não altera nem a propriedade nem as permissões. Na minha opinião, isso nos deixa em uma situação que torna / dev / std * não portátil.
A solução simples é colocar "mesg y" em / etc / profile (ou qualquer outro perfil de nível superior que você queira usar), pois isso altera as permissões do seu dispositivo tty para 0622. Eu realmente não gosto disso, mas provavelmente é melhor do que alterar as regras do udev.
fonte
Como usuário Linux há muito tempo, configurei recentemente um novo sistema Ubuntu 64 bits 12.04 LTS e fiquei confuso com o motivo pelo qual meus scripts bash não estavam funcionando - permissão negada - e, posteriormente, encontrei esse tópico. Eu pensei que o problema poderia ser devido a algo no novo sistema operacional.
No final, descobri que eu tinha estupidamente usado uma ferramenta de interface do usuário para definir permissões no meu
/home
diretório, e o problema estava relacionado à unidade . Para ter certeza, criei umtemp
diretório/opt
e descobri que meus scripts funcionariam muito bem a partir daí. Depois de corrigir as/home
permissões da unidade, tudo voltou ao normal.Um pequeno mistério resolvido. suspiro
fonte
Esta é uma pergunta antiga, mas acho que ainda é muito relevante, portanto, aqui está uma solução que achei que não é mencionada aqui.
Me deparei com essa pergunta, pois também vi problemas em um comando de execução de conta comutada 'su' como este no bash:
Como tudo o que estou tentando fazer é redirecionar o stdout para o stderr, o seguinte alcança o mesmo e funciona mesmo na conta alternada 'su':
fonte