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 su
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 par username
; cette propriété a été accordée lors de la username
connexion. Lorsque vous sudo su username2
, la propriété de /dev/pts/1
ne change pas et username2
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 mais echo hello > /dev/stdout
échoue.
Une solution de contournement serait de faire username2
un membre du groupe tty
, mais cela donnerait la username2
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'à utiliser su
, 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:
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/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 le NEWS
fichier 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_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ème su
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.
ls -l /dev/stdout /dev/stderr
etls -lL /dev/stdout /dev/stderr
?