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


При использовании 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

Есть идеи?


115
2017-12-19 04:12


происхождения




ответы:


Перенаправление вывода (через > оператор) выполняется оболочкой, а не эхо, Вы должны войти в систему как 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"

124
2017-12-19 04:22



Вы не можете запускать эхо с sudo? как насчет результата, который я получил: saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi - saji89
вы можете записать в файл, echo «something»> somehre. Он использует трубку .. Это проблема. - shantanu
Хорошо, если это так, то, пожалуйста, обновите свой ответ, чтобы отразить, что работающее эхо является проблемой только в этом случае. - saji89
Вы не можете просто запустить встроенную оболочку echo как sudo, если вы не делаете что-то вроде sudo bash -c 'echo …'; однако системы POSIX обычно поставляют внешние echo команды, такие как /bin/echo на OS X, которое sudo может выполнять без rigamarole. Таким образом echo команды, которую вы обычно запускаете, и echo команда, которую вы запускаете с помощью sudo, вероятно, две разные, но похожие команды. - kojiro
Если это так, почему ответы на этот вопрос предполагают эхо? askubuntu.com/questions/840431/... - Harsha


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

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

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

  • эхо, работает с 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 содержащий слово «корень». Однако, когда перенаправление вывода не работает в вызывающей оболочке, файл «who.txt» также отсутствует, потому что команда не была вызвана.


71
2017-12-19 05:19



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


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

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

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

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

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

55
2017-12-19 06:50



+1 вход в систему как root - плохая идея для ручной работы, а действительно плохая идея для скриптовых задач. - l0b0
Также, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/null если вы не хотите, чтобы stdout также. - Fabian Tamp


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

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

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

13
2017-12-19 13:53





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.


3
2018-05-28 06:39



Это хорошо. Мы думаем о dd как мы перезаписываем наши некогда большие файловые системы и не понимаем, что это тоже для мирских задач, - и что другие команды как root также наносят большой вред при использовании на неправильных файлах / устройствах. подобно sudo tee, sudo dd конечно, также будет работать с здесь строки, например, sudo dd of=outfile <<<'hello world', [Спасибо за редактирование. NB с sh -c 'cmd', sh является подпроцессом, который является оболочкой, но не является действительно подоболочкой, кроме как в смысле все внешние команды начинаются как один.] - Eliah Kagan


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

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

2
2017-07-29 15:51