Bash'te yeniden yönlendirme ile sudo kullanırken “izin verilmeyen izin” nasıl çözülür?


137

Dosyaları düzenlemeye izin vermek için sudo kullanırken, düzenli olarak 'izin reddedildi' alıyorum.

Örneğin, farem titrek ve halsiz, bu yüzden yoklamayı devre dışı bırakmak istiyorum:

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

Bir parola girmem isteniyor ve sonra:

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

Bu yüzden yoklama özelliğini devre dışı bırakmak için geçici bir değişiklik yapmaya çalıştım:

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

Yine, sistem cevap verdi:

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

Herhangi bir fikir?

Yanıtlar:


156

Çıktı yönlendirmesi ( >operatör üzerinden ) eko tarafından değil kabuk tarafından yapılır . Kök olarak giriş yapmalısınız

sudo -i

Sonra yönlendirme kullanabilirsiniz

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

Aksi takdirde bash dizesini sudo ile çalıştırabilirsiniz.

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"

1
Sudo ile yankı çalıştıramazsın? elde ettiğim sonuç ne oldu:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89 19:12

dosyaya yazabilirsiniz, "bir şey" yankılandı. Boru kullanıyor. Sorun bu.
shantanu

4
Tamam, eğer öyleyse, lütfen yanıtınızı güncelleyin.
saji89

Böyle bir echoşeyi yapmazsanız, kabuk yerleşikini sudo olarak çalıştıramazsınız sudo bash -c 'echo …'; bununla birlikte POSIX sistemleri genellikle OS X'de echoolduğu gibi /bin/echosudo'nun rigamarol olmadan çalıştırabileceği harici bir komut verir. Bu nedenle, echogenellikle çalıştırdığınız echokomut ve sudo ile çalıştırdığınız komut muhtemelen iki farklıdır ancak benzer komutlardır.
kojiro

Bu durumda, neden bu soruya verilen cevaplar yankı gösteriyor? askubuntu.com/questions/840431/…
Harsha

75

Çıktı yönlendirmesi, komutun çağrıldığı kabuk tarafından yapılır . Öyleyse, her şeyi bitlere bölmek, burada neler oluyor *:

  • çağırır kabuk sudo echo "options drm_kms_helper poll=N"çalıştırır sudokomutu echo "options drm_kms_helper poll=N"komut hattı

  • sudo bir şifre ister, superuser kabuğunu açar ve onu geçen komutu echo "options drm_kms_helper poll=N"çalıştıran çağırırecho"options drm_kms_helper poll=N"

  • echo, rootayrıcalıklarla çalışan dizeyi standart çıktısına yazdırır.

  • echokomut sonlandırılır, superuser kabuk çıkar, sudosonlandırılır

  • komutun çağrıldığı kabuk, çıktıyı toplar ve /etc/modprobe.d/local.confyalnızca root tarafından yazılabilen yeniden yönlendirmeye çalışır . "İzin reddedildi" hatası alıyor.

Bunu düzeltmenin yolları için bkz.


(*) - Yukarıdaki sıra, komutun neden başarısız olduğunu anlamaya yardımcı olurken, gerçekte bazı şeyler sıra dışı olur: orijinal kabuk, yeniden yönlendirmeyi fark eder ve sudo ...komutu çağırmadan önce dosyayı yazmak için açmaya çalışır . Dosya açılmadığında, kabuk dosyaya yazması gereken komutu bile çağırmaz (bunu işaret ettiği için @PanosRontogiannis'e teşekkürler).

İşte hızlı bir test:

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

Yukarıdaki testte "root" kelimesini içeren whoami | tee who.txtbir dosya oluşturulacaktı who.txt. Bununla birlikte, çıkış yönlendirmesi çağıran kabuğunda başarısız olursa, komut çağrılmadığı için "who.txt" dosyası da eksiktir.


Daha büyük bir olasılıkla kabuk kendini 'çatal' yapar ve sudo'yu çalıştırmaya çalışmadan önce /etc/modprobe.d/local.conf dosyasını açmaya çalışır. Bu, tanımladığınız ilk 4 adımın aslında dosya açılamadığı için gerçekleşmeyeceği anlamına gelir.
Panos Rontogiannis

1
@PanosRontogiannis: teşekkürler, cevabı güncelledim
Sergey

60

Shantanu'nun cevabına ekleme:

... Veya böyle bir teekomut kullanabilirsiniz :

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

veya eğer bir komutun çıktısı:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll

3
+1 root olarak giriş yapmak, elle çalışmak için kötü bir fikirdir ve scriptli işler için gerçekten kötü bir fikirdir.
l0b0

2
Ayrıca, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nullyazdırılmasını da istemiyorsanız stdout.
Fabian Tamp,

16

Burada bahsetmediğim bir yaklaşım, komut satırının tamamını kendi kabuğunda çalıştırmaktır. sudoManpage kendisi bu yaklaşımın bir örnek verir:

/ Home bölümündeki dizinlerin kullanım listesini yapmak. Bunun, cd ve dosya yeniden yönlendirmesinin çalışmasını sağlamak için komutları bir alt kabukta çalıştırdığını unutmayın.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"

vay teşekkür ederim. basit bir çözüm
Esneklik

4

Başka bir seçenek geçici bir dosya kullanmaktır. Bu bir bash betiğinde kullanışlıdır.

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

3

sudo dd of=

İstediğiniz kadar eklemek için:

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

veya dosyayı sıfırdan yeniden oluşturmak için:

echo inbytes | sudo dd of=outfile

Avantajları:

  • yönlendirme teeyok beri daha güzel/dev/null
  • shaçık alt kabuk olmadığından (ancak yeniden yönlendirme için örtülü olandan) daha güzel
  • ddörneğin status=progresstransferin ilerlemesini görmek için birçok güçlü seçeneğe sahiptir

Sudo komutunu stdinine ilettiği için çalışıyor.


1
Bu iyi. Bir ddzamanlar en iyi dosya sistemlerimizin üzerine nasıl yazdığımızı düşünüyoruz ve bunun sıradan işler için de olduğunu bilmiyoruz - ve root olarak kullanılan diğer komutların da yanlış dosyalarda / cihazlarda kullanıldığında büyük zararlar yarattığını düşünüyoruz. Gibisudo tee , sudo ddelbette birlikte çalışacaktır burada dizeleri , örneğin sudo dd of=outfile <<<'hello world'. [Düzenleme için teşekkürler. NB, ile sh -c 'cmd', shbir dış
işlemdir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.