Jak rozwiązać problem „odmowa dostępu” podczas korzystania z sudo z przekierowaniem w Bash?

137

Gdy używam sudo do zezwalania na edycję plików, regularnie otrzymuję „odmowę dostępu”.

Na przykład moja mysz jest roztrzęsiona i powolna, więc chcę wyłączyć odpytywanie:

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

Zostanie wyświetlony monit o hasło, a następnie otrzymam:

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

Próbowałem więc dokonać tymczasowej zmiany, aby wyłączyć odpytywanie, używając:

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

Po raz kolejny system odpowiedział:

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

Jakieś pomysły?

Jacek
źródło

Odpowiedzi:

156

Przekierowanie danych wyjściowych (za pośrednictwem >operatora) odbywa się przez powłokę, a nie przez echo . Musisz zalogować się jako root

sudo -i

Następnie możesz użyć przekierowania

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

W przeciwnym razie możesz uruchomić ciąg bash z sudo

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
shantanu
źródło
1
Nie możesz uruchomić echa w sudo? a co z rezultatem, który otrzymałem:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89
możesz pisać na plikach, powtarzać „coś”> gdzieś. Używa rury. To jest problem.
shantanu,
4
Ok, jeśli tak jest, to proszę zaktualizuj swoją odpowiedź, aby odzwierciedlić, że uruchomione echo stanowi problem tylko w tym przypadku.
saji89,
Nie możesz po prostu uruchomić wbudowanej powłoki echojako sudo, chyba że zrobisz coś takiego sudo bash -c 'echo …'; jednak systemy POSIX zwykle dostarczają zewnętrzne echopolecenie, takie jak /bin/echona OS X, które sudo może wykonać bez rigamarole. Zatem echopolecenie, które zwykle uruchamiasz i echopolecenie uruchamiane za pomocą sudo, to prawdopodobnie dwa różne, ale podobne polecenia.
kojiro
Jeśli tak, to dlaczego odpowiedzi na to pytanie sugerują echo? askubuntu.com/questions/840431/…
Harsha
75

Przekierowanie danych wyjściowych jest wykonywane przez powłokę, z której wywołano polecenie . Rozbijając wszystko na strzępy, oto co się dzieje *:

  • wywołuje powłokę sudo echo "options drm_kms_helper poll=N", która wykonuje sudopolecenie za pomocą echo "options drm_kms_helper poll=N"wiersza poleceń

  • sudo prosi o hasło, otwiera powłokę superużytkownika i wywołuje echo "options drm_kms_helper poll=N", echoprzekazując polecenie"options drm_kms_helper poll=N"

  • echo, działające z rootuprawnieniami, wypisuje ciąg na standardowe wyjście.

  • echopolecenie kończy się, kończy działanie superużytkownika, sudokończy się

  • powłoka, z której wywołano polecenie, zbiera dane wyjściowe i próbuje je przekierować /etc/modprobe.d/local.conf, co można zapisać tylko przez root. Otrzymuje błąd „odmowa uprawnień”.

Aby dowiedzieć się, jak to naprawić, patrz odpowiedź @shantanu.


(*) - podczas gdy powyższa sekwencja pomaga zrozumieć, dlaczego polecenie kończy się niepowodzeniem, w rzeczywistości rzeczy dzieją się nieco poza kolejnością: oryginalna powłoka zauważa przekierowanie i próbuje otworzyć plik do zapisu przed wywołaniem sudo ...polecenia. Podczas otwierania pliku nie powiedzie się powłoka nawet nie wywołuje polecenia, które miało zostać zapisane do pliku (dzięki @PanosRontogiannis za zwrócenie na to uwagi).

Oto szybki test:

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

W powyższym teście whoami | tee who.txtzamierzałem utworzyć plik o nazwie who.txtzawierającej słowo „root”. Jednak gdy przekierowanie wyjścia nie powiedzie się w powłoce wywołującej, brakuje również pliku „who.txt”, ponieważ polecenie nie zostało wywołane.

Siergiej
źródło
Bardziej prawdopodobne jest, że powłoka „rozwidla się” i próbuje otworzyć /etc/modprobe.d/local.conf przed próbą wykonania „sudo”, co oznacza, że ​​pierwsze 4 kroki, które opisujesz, nigdy się nie zdarzają, ponieważ pliku nie można otworzyć.
Panos Rontogiannis
1
@PanosRontogiannis: dzięki, zaktualizowałem odpowiedź
Sergey
60

Dodając do odpowiedzi Shantanu:

... Lub możesz użyć takiego teepolecenia:

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

lub jeśli jest to wynik polecenia:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
Nieuprawny
źródło
3
+1 do zalogowania się jako root to zły pomysł na pracę ręczną i naprawdę zły pomysł na zadania skryptowe.
l0b0,
2
Ponadto, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nulljeśli nie chcesz, aby drukowanie stdoutrównież.
Fabian Tamp
16

Podejście, którego nie widziałem tutaj, to po prostu wykonanie całej linii poleceń we własnej powłoce. Sama strona sudoman podaje przykład takiego podejścia:

Aby utworzyć listę wykorzystania katalogów na partycji / home. Zauważ, że uruchamia to polecenia w podpowłoce, aby przekierowanie dysku CD i pliku działało.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
kojiro
źródło
wow dzięki. proste rozwiązanie
Resilience
4

Inną opcją jest użycie pliku tymczasowego. Jest to przydatne w skrypcie bash.

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever
użytkownik545424
źródło
3

sudo dd of=

Aby dołączyć, jak chcesz:

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

lub aby odtworzyć plik od zera:

echo inbytes | sudo dd of=outfile

Zalety:

  • ładniejsze niż teebez /dev/nullprzekierowania
  • ładniejsze niż shodkąd brak wyraźnej podpowłoki (ale domyślnej dla przekierowania)
  • ddma wiele zaawansowanych opcji, np. status=progressaby zobaczyć postęp transferu

Działa, ponieważ sudo przekazuje stdin do polecenia.

Ciro Santilli
źródło
1
To jest dobre. Myślimy o ddtym, jak nadpisujemy nasze niegdyś wspaniałe systemy plików i nie zdajemy sobie sprawy, że jest to również do przyziemnych zadań - i że inne polecenia jako root również powodują duże szkody, jeśli są używane na niewłaściwych plikach / urządzeniach. Podobnie jaksudo tee , sudo ddoczywiście będzie również działać z ciągami tutaj , np sudo dd of=outfile <<<'hello world'. [Dzięki za edycję. NB z sh -c 'cmd', shto podproces, który jest powłoką, ale tak naprawdę nie jest podpowłoką, z wyjątkiem tego, że wszystkie zewnętrzne polecenia zaczynają się jako jedna.]
Eliah Kagan