Ich denke nicht, dass dies eine rein heftige Angelegenheit ist.
In einem Kommentar sagten Sie, dass Sie diesen Fehler danach gesehen haben
sudo su username2
wenn Sie angemeldet sind als username
. Es ist das su
, was das Problem auslöst.
/dev/stdout
ist ein Symlink zu /proc/self/fd/1
, der zum Beispiel ein Symlink zu ist /dev/pts/1
. /dev/pts/1
, das ein Pseudoterminal ist, im Besitz von und beschreibbar von username
; Dieses Eigentumsrecht wurde gewährt, als Sie username
angemeldet waren. Wenn Sie sudo su username2
das Eigentumsrecht von /dev/pts/1
nicht ändern, undusername2
keine Schreibberechtigung.
Ich würde argumentieren, dass dies ein Fehler ist. /dev/stdout
sollte eigentlich ein Alias für den Standardausgabestream sein, aber hier sehen wir eine Situation, in der echo hello
funktioniert, aber echo hello > /dev/stdout
fehlschlägt.
Ein Workaround wäre, username2
ein Mitglied der Gruppe zu machen tty
, aber das würde die username2
Erlaubnis geben , an jede beliebige Zahl zu schreiben , was wahrscheinlich unerwünscht ist.
Eine andere Problemumgehung besteht darin, sich beim username2
Konto anzumelden, anstatt es zu verwenden su
, sodass /dev/stdout
auf ein neu zugewiesenes Pseudoterminal von verwiesen wird username2
. Dies ist möglicherweise nicht praktikabel.
Eine andere Problemumgehung wäre, Ihre Skripte so zu ändern, dass sie nicht auf /dev/stdout
und verweisen /dev/stderr
. Ersetzen Sie zum Beispiel Folgendes:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
dadurch:
echo OUT
echo ERR 1>&2
Ich sehe dies auf meinem eigenen System, Ubuntu 12.04, mit Bash 4.2.24 - obwohl das Bash-Dokument ( info bash
) auf meinem System das besagt /dev/stdout
und /dev/stderr
speziell behandelt wird, wenn es in Umleitungen verwendet wird. Aber auch wenn bash diese Namen nicht speziell behandelt, sollten sie dennoch als Entsprechung für die Standard-E / A-Streams fungieren. (POSIX erwähnt dies nicht /dev/std{in,out,err}
, daher kann es schwierig sein zu argumentieren, dass dies ein Fehler ist.)
Betrachtet man alte Versionen von Bash, so impliziert die Dokumentation, dass /dev/stdout
ua speziell behandelt wird, ob die Dateien existieren oder nicht. Die Funktion wurde in Bash 2.04 eingeführt, und in der NEWS
Datei für diese Version heißt es:
Der Umleitungscode behandelt jetzt speziell mehrere Dateinamen: / dev / fd / N, / dev / stdin, / dev / stdout und / dev / stderr, unabhängig davon, ob sie im Dateisystem vorhanden sind oder nicht.
Wenn Sie jedoch den Quellcode untersuchen ( redir.c
), werden Sie feststellen , dass diese spezielle Behandlung nur aktiviert ist , wenn das Symbol HAVE_DEV_STDIN
definiert ist (dies wird bestimmt, wenn die Bash aus dem Quellcode erstellt wird).
Soweit ich das beurteilen kann, hat keine veröffentlichte Version von bash die besondere Behandlung von gemacht/dev/stdout
et al an Bedingungen geknüpft - es sei denn, eine Distribution hat sie gepatcht.
Eine andere Problemumgehung (die ich nicht ausprobiert habe) wäre, die Bash-Quellen zu greifen und sie zu modifizieren, um sie redir.c
zu etwas Besonderem zu machen/dev/*
Behandlung zu verhindern, und Ihre neu erstellte Version zu verwenden, anstatt diejenige, die mit Ihrem System geliefert wurde. Dies ist jedoch wahrscheinlich übertrieben.
ZUSAMMENFASSUNG :
Ihr Betriebssystem behandelt wie meins die Eigentumsrechte und Berechtigungen von /dev/stdout
und nicht /dev/stderr
richtig. Bash behandelt diese Namen angeblich speziell in Umleitungen, aber tatsächlich nur, wenn die Dateien nicht existieren. Das wäre egal, wenn /dev/stdout
und /dev/stderr
richtig funktioniert. Dieses Problem tritt nur auf, wenn Sie ein su
anderes Konto haben oder etwas Ähnliches tun. Wenn Sie sich einfach bei einem Konto anmelden, sind die Berechtigungen korrekt.
ls -l /dev/stdout /dev/stderr
undls -lL /dev/stdout /dev/stderr
?