Après la mise à niveau vers une nouvelle version, mes bash
scripts commencent à cracher des erreurs:
bash: /dev/stderr: Permission denied
dans les versions précédentes, Bash reconnaîtrait en interne ces noms de fichiers (c'est pourquoi cette question n'est pas un doublon de celui-ci ) et ferait ce qu'il fallait (tm) , cependant, cela n'a plus fonctionné maintenant. Que puis-je faire pour pouvoir réexécuter mes scripts avec succès?
J'ai essayé d'ajouter l'utilisateur exécutant le script au groupe tty
, mais cela ne fait aucune différence (même après la déconnexion et la reconnexion).
Je peux reproduire cela sur la ligne de commande sans problème:
$ 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
Sur un système plus ancien (Ubuntu 10.04):
$ echo $BASH_VERSION
4.1.5(1)-release
bash
permissions
stdout
0xC0000022L
la source
la source
ls -l /dev/stdout /dev/stderr
etls -lL /dev/stdout /dev/stderr
?sudo su username2 -
...echo $BASH_VERSION
Réponses:
Je ne pense pas que ce soit entièrement un problème bash.
Dans un commentaire, vous avez dit avoir vu cette erreur après avoir fait
une fois connecté en tant que
username
. C'est cesu
qui déclenche le problème./dev/stdout
est un lien symbolique/proc/self/fd/1
, qui est un lien symbolique, par exemple,/dev/pts/1
./dev/pts/1
, qui est un pseudoterminal, appartient et est accessible en écriture parusername
; cette propriété a été accordée lors de lausername
connexion. Lorsque voussudo su username2
, la propriété de/dev/pts/1
ne change pas etusername2
n'a pas la permission d'écriture.Je dirais que c'est un bug.
/dev/stdout
devrait être, en effet, un alias pour le flux de sortie standard, mais ici nous voyons une situation oùecho hello
fonctionne maisecho hello > /dev/stdout
échoue.Une solution de contournement serait de faire
username2
un membre du groupetty
, mais cela donnerait lausername2
permission d'écrire à n'importe quel terminal, ce qui n'est probablement pas souhaitable.Une autre solution de contournement consisterait à se connecter au
username2
compte plutôt qu'à utilisersu
, de sorte que/dev/stdout
pointe vers un pseudoterminal nouvellement alloué appartenant àusername2
. Cela pourrait ne pas être pratique.Une autre solution consiste à modifier vos scripts afin qu'ils ne se réfèrent pas à
/dev/stdout
et/dev/stderr
; par exemple, remplacez ceci:par ça:
Je vois cela sur mon propre système, Ubuntu 12.04, avec bash 4.2.24 - même si le document bash (
info bash
) sur mon système le dit/dev/stdout
et/dev/stderr
est traité spécialement lorsqu'il est utilisé dans les redirections. Mais même si bash ne traite pas ces noms spécialement, ils devraient quand même agir comme des équivalents pour les flux d'E / S standard. (POSIX ne le mentionne pas/dev/std{in,out,err}
, il peut donc être difficile de prétendre qu'il s'agit d'un bogue.)En regardant les anciennes versions de bash, la documentation implique que
/dev/stdout
et al sont traités spécialement, que les fichiers existent ou non. La fonctionnalité a été introduite dans bash 2.04, et leNEWS
fichier de cette version indique:Mais si vous examinez le code source (
redir.c
), vous verrez que cette gestion spéciale n'est activée que si le symboleHAVE_DEV_STDIN
est défini (ceci est déterminé lorsque bash est construit à partir de la source).Pour autant que je sache, aucune version publiée de bash n'a rendu
/dev/stdout
inconditionnelle la gestion spéciale de et al - à moins qu'une distribution ne l'ait corrigé.Une autre solution (que je n'ai pas essayée) serait donc de récupérer les sources bash , de les modifier
redir.c
pour rendre/dev/*
inconditionnelle la gestion spéciale et d'utiliser votre version reconstruite plutôt que celle fournie avec votre système. C'est probablement exagéré, cependant.SOMMAIRE :
Votre système d' exploitation, comme le mien, gère pas la propriété et les autorisations de
/dev/stdout
et/dev/stderr
correctement. bash est censé traiter ces noms spécialement dans les redirections, mais en fait il ne le fait que si les fichiers n'existent pas. Ce ne serait pas grave si/dev/stdout
et/dev/stderr
fonctionnait correctement. Ce problèmesu
n'apparaît que lorsque vous accédez à un autre compte ou faites quelque chose de similaire; si vous vous connectez simplement à un compte, les autorisations sont correctes.la source
pam_ck_connector.so
)./proc/self/fd/1
ses autorisations sont mises à jour, mais cela est inutile, car il s'agit d'un lien symbolique. Cela se produit également sur Fedora, ce qui semble exclure ConsoleKit.En fait, la raison en est que udev définit spécifiquement les autorisations sur 0620 sur les périphériques tty et que su ne change ni la propriété ni les autorisations. À mon avis, cela nous place dans une situation qui rend / dev / std * non portable.
La solution simple est de mettre "mesg y" dans / etc / profile (ou quel que soit le profil de premier niveau que vous souhaitez utiliser) car cela change les autorisations de votre périphérique tty en 0622. Je n'aime pas vraiment ça mais c'est probablement mieux que de changer les règles udev.
la source
En tant qu'utilisateur Linux de longue date, j'ai récemment mis en place un nouveau système Ubuntu 64 bits 12.04 LTS et je ne savais pas pourquoi mes scripts bash ne fonctionnaient pas - autorisation refusée - et j'ai par la suite trouvé ce fil. J'ai pensé que le problème pourrait être dû à quelque chose dans le nouveau système d'exploitation.
En fin de compte, il s'est avéré que j'avais stupidement utilisé un outil d'interface utilisateur pour définir des autorisations sur mon
/home
répertoire, et le problème était lié au lecteur . Pour être sûr, j'ai créé untemp
répertoire/opt
et trouvé que mes scripts fonctionneraient très bien à partir de là. Une fois que j'ai corrigé les/home
autorisations de lecteur, tout était redevenu normal.Un petit mystère résolu. soupir
la source
C'est une vieille question, mais je pense toujours très pertinente, donc voici une solution que j'ai trouvée qui n'est pas mentionnée ici.
Je suis tombé sur cette question car j'ai également vu des problèmes dans une commande d'exécution de compte commuté «su» comme celle-ci dans bash:
Étant donné que tout ce que j'essaie de faire est de rediriger stdout vers stderr, ce qui suit obtient le même résultat, et cela fonctionne même dans le compte commuté «su»:
la source