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
sudo su username2
une fois connecté en tant que username. C'est ce suqui déclenche le problème.
/dev/stdoutest 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 par username; cette propriété a été accordée lors de la usernameconnexion. Lorsque vous sudo su username2, la propriété de /dev/pts/1ne change pas et username2n'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 hellofonctionne mais echo hello > /dev/stdoutéchoue.
Une solution de contournement serait de faire username2un membre du groupe tty, mais cela donnerait la username2permission d'écrire à n'importe quel terminal, ce qui n'est probablement pas souhaitable.
Une autre solution de contournement consisterait à se connecter au username2compte plutôt qu'à utiliser su, de sorte que /dev/stdoutpointe 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/stdoutet /dev/stderr; par exemple, remplacez ceci:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
par ça:
echo OUT
echo ERR 1>&2
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/stdoutet /dev/stderrest 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/stdoutet al sont traités spécialement, que les fichiers existent ou non. La fonctionnalité a été introduite dans bash 2.04, et le NEWSfichier de cette version indique:
Le code de redirection gère désormais plusieurs noms de fichiers spécialement: / dev / fd / N, / dev / stdin, / dev / stdout et / dev / stderr, qu'ils soient ou non présents dans le système de fichiers.
Mais si vous examinez le code source ( redir.c), vous verrez que cette gestion spéciale n'est activée que si le symbole HAVE_DEV_STDINest 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/stdoutinconditionnelle 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.cpour 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/stdoutet /dev/stderrcorrectement. 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/stdoutet /dev/stderrfonctionnait correctement. Ce problème sun'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.
ls -l /dev/stdout /dev/stderretls -lL /dev/stdout /dev/stderr?