Wie löse ich "Erlaubnis verweigert", wenn ich sudo mit Umleitung in Bash verwende?

137

Wenn ich sudo verwende, um Änderungen an Dateien zuzulassen, wird mir regelmäßig die Berechtigung verweigert.

Zum Beispiel ist meine Maus unruhig und träge, deshalb möchte ich das Polling deaktivieren:

sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf

Ich werde nach einem Passwort gefragt und erhalte dann:

bash: /etc/modprobe.d/local.conf: Permission denied

Daher habe ich versucht, eine vorübergehende Änderung vorzunehmen, um die Abfrage zu deaktivieren.

sudo echo N> /sys/module/drm_kms_helper/parameters/poll

Das System antwortete erneut mit:

bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied

Irgendwelche Ideen?

Jack
quelle

Antworten:

156

Die Ausgabeumleitung (über den >Operator) erfolgt durch die Shell und nicht durch Echo . Sie müssen sich als root anmelden

sudo -i

Dann können Sie die Umleitung verwenden

echo N> /sys/module/drm_kms_helper/parameters/poll

Andernfalls können Sie bash string mit sudo ausführen

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
Shantanu
quelle
1
Sie können mit sudo kein Echo ausführen? Was ist mit dem Ergebnis, das ich bekam:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
Saji89
Sie können in eine Datei schreiben und "etwas"> irgendwo wiedergeben. Es benutzt Pipe. Das ist das Problem.
Shantanu
4
Wenn dies der Fall ist, aktualisieren Sie bitte Ihre Antwort, um zu berücksichtigen, dass das laufende Echo nur in diesem Fall ein Problem darstellt.
Saji89
Sie können die eingebaute Shell nicht einfach echoals sudo ausführen , es sei denn, Sie tun etwas Ähnliches sudo bash -c 'echo …'. POSIX-Systeme stellen jedoch in der Regel einen externen echoBefehl bereit, z. B. /bin/echounter OS X, den sudo ohne rigamarole ausführen kann. Daher sind der echoBefehl , den Sie normalerweise ausführen, und der echoBefehl, den Sie mit sudo ausführen, wahrscheinlich zwei verschiedene, aber ähnliche Befehle.
Kojiro
Wenn dies der Fall ist, warum deuten die Antworten auf diese Frage auf ein Echo hin? askubuntu.com/questions/840431/…
Harsha
75

Die Ausgabeumleitung erfolgt über die Shell, von der aus der Befehl aufgerufen wurde . Also, brechen Sie alles in Stücke, hier, was passiert *:

  • Shell ruft auf sudo echo "options drm_kms_helper poll=N", die sudoBefehl mit der echo "options drm_kms_helper poll=N"Befehlszeile ausführt

  • sudo fragt nach einem Passwort, öffnet die Superuser-Shell und ruft auf echo "options drm_kms_helper poll=N", wodurch der echoBefehl ausgeführt wird, der sie übergibt"options drm_kms_helper poll=N"

  • echo wird mit rootBerechtigungen ausgeführt und druckt die Zeichenfolge auf die Standardausgabe.

  • echoBefehl wird beendet, Superuser-Shell wird sudobeendet , beendet

  • Die Shell, von der aus der Befehl aufgerufen wurde, sammelt die Ausgabe und versucht sie umzuleiten. /etc/modprobe.d/local.confDiese kann nur von root geschrieben werden. Es wird der Fehler "Berechtigung verweigert" ausgegeben.

Informationen zur Behebung dieses Problems finden Sie unter @shantanu answer.


(*) - Während die obige Sequenz hilft zu verstehen, warum der Befehl fehlschlägt, passieren die Dinge in Wirklichkeit etwas in der falschen Reihenfolge: Die ursprüngliche Shell bemerkt die Umleitung und versucht, die Datei zum Schreiben zu öffnen, bevor sie den sudo ...Befehl aufruft . Wenn das Öffnen der Datei fehlschlägt, ruft die Shell nicht einmal den Befehl auf, der in die Datei schreiben sollte (danke an @PanosRontogiannis für diesen Hinweis).

Hier ist ein kurzer Test:

$ touch ./onlyroot.txt
$ sudo chown root:root ./onlyroot.txt
$ sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied

Im obigen Test whoami | tee who.txtwurde eine Datei who.txtmit dem Namen "root" erstellt. Wenn jedoch die Ausgabeumleitung in der aufrufenden Shell fehlschlägt, fehlt auch die Datei "who.txt", da der Befehl nicht aufgerufen wurde.

Sergey
quelle
Es ist wahrscheinlicher, dass die Shell sich selbst 'gabelt' und versucht, /etc/modprobe.d/local.conf zu öffnen, bevor sie versucht, sudo 'auszuführen', was bedeutet, dass die ersten 4 Schritte, die Sie beschreiben, nie tatsächlich passieren, weil die Datei nicht geöffnet werden kann.
Panos Rontogiannis
1
@PanosRontogiannis: danke, ich habe die Antwort aktualisiert
Sergey
60

Hinzufügen zu Shantanus Antwort:

... Oder Sie könnten einen teeBefehl wie diesen verwenden:

sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10

oder wenn es eine Befehlsausgabe ist:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
Ohne Titel
quelle
3
+1 Anmelden als root ist eine schlechte Idee für manuelle Arbeit und eine wirklich schlechte Idee für Skriptaufgaben.
l0b0
2
Auch, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nullwenn Sie nicht möchten, dass es auch gedruckt wird stdout.
Fabian Tamp
16

Ein Ansatz, den ich hier nicht gesehen habe, besteht darin, einfach die gesamte Befehlszeile in einer eigenen Shell auszuführen. Die sudoManpage selbst gibt ein Beispiel für diesen Ansatz:

So erstellen Sie eine Verwendungsliste der Verzeichnisse in der / home-Partition. Beachten Sie, dass dadurch die Befehle in einer Sub-Shell ausgeführt werden, damit die Umleitung von CD und Datei funktioniert.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
Kojiro
quelle
Wow, danke. eine einfache Lösung
Resilience
4

Eine andere Möglichkeit ist die Verwendung einer temporären Datei. Dies ist in einem Bash-Skript nützlich.

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever
user545424
quelle
3

sudo dd of=

So hängen Sie an, wie Sie möchten:

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc

oder um die Datei von Grund auf neu zu erstellen:

echo inbytes | sudo dd of=outfile

Vorteile:

  • schöner als teeda keine /dev/nullumleitung
  • schöner als shda keine explizite subshell (aber eine implizite für die umleitung)
  • ddhat viele leistungsstarke Optionen, z. B. status=progressum den Übertragungsfortschritt zu sehen

Funktioniert, weil sudo stdin an den Befehl weiterleitet.

Ciro Santilli ist ein Schauspieler
quelle
1
Das ist gut. Wir denken daran, ddwie wir unsere einst so tollen Dateisysteme überschreiben und nicht erkennen, dass dies auch für alltägliche Aufgaben gedacht ist - und dass andere Befehle als root ebenfalls großen Schaden anrichten, wenn sie auf den falschen Dateien / Geräten verwendet werden. Wiesudo tee , sudo ddwird natürlich auch mit der Arbeit hier Strings , zum Beispiel sudo dd of=outfile <<<'hello world'. [Danke für die Bearbeitung. NB with sh -c 'cmd', shist ein Subprozess, der eine Shell ist, aber nicht wirklich eine Subshell, außer in dem Sinne, dass alle externen Befehle als eins beginnen.]
Eliah Kagan