bash: / dev / stderr: Berechtigung verweigert

19

Nach dem Upgrade auf eine neue Release-Version werden in meinen bashSkripten Fehler angezeigt:

bash: /dev/stderr: Permission denied

In früheren Versionen hat Bash diese Dateinamen intern erkannt (daher ist diese Frage kein Duplikat von dieser ist ) und das Richtige getan (tm) , dies hat jedoch jetzt aufgehört zu funktionieren. Was kann ich tun, um meine Skripte wieder erfolgreich ausführen zu können?

Ich habe versucht, den Benutzer, der das Skript ttyausführt , zur Gruppe hinzuzufügen , aber dies macht keinen Unterschied (auch nach dem Abmelden und erneuten Anmelden).

Ich kann dies problemlos auf der Kommandozeile reproduzieren:

$ 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

Auf einem älteren System (Ubuntu 10.04):

$ echo $BASH_VERSION
4.1.5(1)-release
0xC0000022L
quelle
1
Was ist die Ausgabe von ls -l /dev/stdout /dev/stderrund ls -lL /dev/stdout /dev/stderr?
Keith Thompson
@ Keith: siehe meine bearbeitete Frage. Bedeutet das, dass Bash die interne Abwicklung komplett aufgegeben hat? Auf älteren Systemen existierten diese Symlinks nicht und dennoch funktionierte der Code problemlos. Beachten Sie, dass dies imitiert ausgeführt wird über sudo su username2 -...
0xC0000022L
Welche Bash-Version verwenden Sie? echo $BASH_VERSION
jippie
1
Was sind die alten und neuen Versionen (vor und nach Ihrem Betriebssystem und von Bash?
Keith Thompson

Antworten:

41

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/stdoutist 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 usernameangemeldet waren. Wenn Sie sudo su username2das Eigentumsrecht von /dev/pts/1nicht ä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 hellofunktioniert, aber echo hello > /dev/stdoutfehlschlägt.

Ein Workaround wäre, username2ein Mitglied der Gruppe zu machen tty, aber das würde die username2Erlaubnis geben , an jede beliebige Zahl zu schreiben , was wahrscheinlich unerwünscht ist.

Eine andere Problemumgehung besteht darin, sich beim username2Konto anzumelden, anstatt es zu verwenden su, sodass /dev/stdoutauf 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/stdoutund 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/stdoutund /dev/stderrspeziell 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/stdoutua speziell behandelt wird, ob die Dateien existieren oder nicht. Die Funktion wurde in Bash 2.04 eingeführt, und in der NEWSDatei 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_STDINdefiniert 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.czu 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/stdoutund nicht /dev/stderrrichtig. Bash behandelt diese Namen angeblich speziell in Umleitungen, aber tatsächlich nur, wenn die Dateien nicht existieren. Das wäre egal, wenn /dev/stdoutund /dev/stderrrichtig funktioniert. Dieses Problem tritt nur auf, wenn Sie ein suanderes Konto haben oder etwas Ähnliches tun. Wenn Sie sich einfach bei einem Konto anmelden, sind die Berechtigungen korrekt.

Keith Thompson
quelle
Das Eigentum des TTY sollte sich ändern. Dafür gibt es ConsoleKit pam_ck_connector.so.
Mikel
Eigentlich könnte ich mich irren. Müssen mehr graben.
Mikel
Auf meinen Systemen werden /proc/self/fd/1die Berechtigungen aktualisiert, aber das ist sinnlos, da es sich um einen Symlink handelt. Passiert auch auf Fedora, was ConsoleKit anscheinend ausschließt.
Mikel
1

Eigentlich liegt das daran, dass udev die Berechtigungen auf tty-Geräten spezifisch auf 0620 setzt und su weder den Besitz noch die Berechtigungen ändert, noch sollte es dies tun. Meiner Ansicht nach befinden wir uns in einer Situation, in der / dev / std * nicht portierbar ist.

Die einfache Lösung besteht darin, "mesg y" in / etc / profile (oder in ein beliebiges oberstes Profil, das Sie verwenden möchten) einzufügen, da dies die Berechtigungen Ihres tty-Geräts in 0622 ändert. Das gefällt mir nicht wirklich, aber es ist wahrscheinlich besser als die udev Regeln zu ändern.

Wheely
quelle
"msg y" funktioniert nicht
Luciano
Warten Sie ... Vielleicht sucht Bash nach mehreren Dateinamen, insbesondere wenn diese in Umleitungen auf der Manpage von Bash verwendet werden.
0xC0000022L
0

Als langjähriger Linux-Benutzer habe ich kürzlich ein neues Ubuntu 64-Bit 12.04 LTS-System eingerichtet und war verblüfft, warum meine Bash-Skripte nicht funktionierten - Berechtigung verweigert - und fand anschließend diesen Thread. Ich dachte, das Problem könnte an etwas im neuen Betriebssystem liegen.

Am Ende stellte sich heraus, dass ich dummerweise ein UI-Tool verwendet hatte, um Berechtigungen für mein /homeVerzeichnis festzulegen , und das Problem war mit dem Laufwerk verbunden. Um sicherzugehen, habe ich ein tempVerzeichnis erstellt /optund festgestellt, dass meine Skripte von dort aus problemlos ausgeführt werden können. Einmal habe ich das behoben/home Laufwerksberechtigungen repariert hatte, war alles wieder normal.

Ein kleines Rätsel gelöst. Seufzer

Ichiro Furusato
quelle
2
Dies muss ein anderer Fehler gewesen sein. Änderungen in / home wirken sich nicht auf / dev aus.
ott--
-1

Dies ist eine alte Frage, aber ich denke immer noch sehr relevant, daher habe ich hier eine Lösung gefunden, die hier nicht erwähnt wird.

Ich bin auf diese Frage gestoßen, da ich in Bash auch Probleme mit einem Befehl zum Ausführen eines "su" -geschalteten Kontos gesehen habe:

echo test > /dev/stderr

Da ich nur versuche, stdout nach stderr umzuleiten, wird das Gleiche erreicht, und dies funktioniert auch bei einem "su" -geschalteten Konto:

echo test 1>&2
Marcin K
quelle