Как решить «отказано в разрешении» при использовании sudo с перенаправлением в Bash?

138

Когда я использую sudo, чтобы разрешить редактирование файлов, я регулярно получаю «разрешение запрещено».

Например, моя мышь нервная и вялая, поэтому я хочу отключить опрос:

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

Мне предлагается ввести пароль, а затем получить:

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

Поэтому я попытался сделать временное изменение, чтобы отключить опрос, используя:

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

И снова система ответила:

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

Есть идеи?

Джек
источник

Ответы:

158

Перенаправление вывода (через >оператора) выполняется оболочкой, а не echo . Вы должны войти в систему как root

sudo -i

Тогда вы можете использовать перенаправление

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

В противном случае вы можете запустить строку bash с помощью sudo

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
Шантану
источник
1
Вы не можете запустить эхо с Sudo? Что насчет результата, который я получил:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89
Вы можете написать в файл, эхо "что-то"> Somewhre. Это использует трубу .. В этом проблема.
Шантану
4
Хорошо, если это так, пожалуйста, обновите свой ответ, чтобы отразить, что запуск echo является проблемой только в этом случае.
saji89
Вы не можете просто запустить встроенную оболочку echoкак sudo, если вы не сделаете что-то подобное sudo bash -c 'echo …'; однако системы POSIX обычно предоставляют внешнюю echoкоманду, такую ​​как /bin/echoв OS X, которую sudo может выполнить без rigamarole. Таким образом, echoкоманда, которую вы обычно запускаете, и echoкоманда, которую вы запускаете с помощью sudo, вероятно, являются двумя разными, но похожими командами.
Кодзиро
Если это так, то почему ответы на этот вопрос наводят на мысль? askubuntu.com/questions/840431/…
Харша
75

Перенаправление вывода выполняется оболочкой, из которой была вызвана команда . Итак, разбивая все на кусочки, вот что происходит *:

  • вызывает оболочку sudo echo "options drm_kms_helper poll=N", которая выполняет sudoкоманду с echo "options drm_kms_helper poll=N"командной строкой

  • Судо запрашивает пароль, открывает суперпользователя оболочку и вызывает echo "options drm_kms_helper poll=N", который запускает echoкоманду передачи его"options drm_kms_helper poll=N"

  • echo, работающий с rootпривилегиями, выводит строку в стандартный вывод.

  • echoкоманда завершается, суперпользовательская оболочка завершается, sudoзавершается

  • оболочка, из которой была вызвана команда, собирает выходные данные и пытается перенаправить их /etc/modprobe.d/local.conf, что доступно для записи только пользователю root. Получает ошибку «Отказано в доступе».

Чтобы узнать, как это исправить, смотрите ответ @shantanu.


(*) - хотя приведенная выше последовательность помогает понять, почему команда терпит неудачу, в действительности все происходит несколько не по порядку: исходная оболочка замечает перенаправление и пытается открыть файл для записи перед вызовом sudo ...команды. При открытии файла происходит сбой, оболочка даже не вызывает команду, которая должна была записать файл (спасибо @PanosRontogiannis за это).

Вот быстрый тест:

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

В тесте выше whoami | tee who.txtсобирался создать файл с именем, who.txtсодержащим слово «root». Однако, когда перенаправление вывода завершается неудачно в вызывающей оболочке, файл who.txt также отсутствует, так как команда не была вызвана.

Сергей
источник
Скорее всего, оболочка «разветвляется» сама и пытается открыть /etc/modprobe.d/local.conf, прежде чем пытаться «выполнить» sudo, что означает, что первые 4 шага, которые вы описываете, на самом деле никогда не происходят, потому что файл не может быть открыт.
Panos Rontogiannis
1
@PanosRontogiannis: спасибо, я обновил ответ
Сергей
60

Добавление к ответу Шантану:

... Или вы можете использовать такую teeкоманду:

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

или если вывод команды:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
Без названия
источник
3
+1 вход в систему как root - плохая идея для ручной работы и действительно плохая идея для скриптовых задач.
10
2
Кроме того, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nullесли вы не хотите, чтобы печать stdoutтоже.
Фабиан Тамп
16

Подход, о котором я не упомянул, это просто выполнить всю командную строку в своей собственной оболочке. Сама sudoстраница руководства приводит пример такого подхода:

Составить список использования каталогов в разделе / ​​home. Обратите внимание, что это запускает команды в под-оболочке, чтобы заставить работать перенаправление компакт-дисков и файлов.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
Кодзиро
источник
Вау, спасибо. простое решение
устойчивость
4

Другой вариант - использовать временный файл. Это полезно в скрипте bash.

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever
user545424
источник
3

sudo dd of=

Чтобы добавить, как вы хотите:

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

или воссоздать файл с нуля:

echo inbytes | sudo dd of=outfile

Преимущества:

  • приятнее, чем teeбез /dev/nullперенаправления
  • приятнее, чем shотсутствие явной подоболочки (но неявной для перенаправления)
  • ddимеет много мощных опций, например, status=progressчтобы увидеть прогресс передачи

Работает потому, что sudo пересылает stdin в команду.

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
источник
1
Это хорошо. Мы думаем о ddтом, как мы перезаписываем наши когда-то великолепные файловые системы, и не понимаем, что это тоже для мирских задач - и что другие команды от имени root также наносят большой вред, если используются на неправильных файлах / устройствах. Какsudo tee и , sudo ddконечно , также работать с здесь строк , например, sudo dd of=outfile <<<'hello world'. [Спасибо за редактирование. NB с sh -c 'cmd', shявляется подпроцессом, который является оболочкой, но на самом деле не подоболочкой, за исключением того, что все внешние команды начинаются как единое целое.]
Элия ​​Каган