При использовании sudo с перенаправлением я получаю «разрешение отклонено»

104

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

Любые идеи?

    
задан Jack 19.12.2012 в 04:12
источник

6 ответов

111

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

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

  • 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"

  • 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» также отсутствует, поскольку команда не была вызвана.

    
ответ дан Sergey 19.12.2012 в 05:19
53

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

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

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

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

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
    
ответ дан Untitled 19.12.2012 в 06:50
12

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

  

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

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
    
ответ дан kojiro 19.12.2012 в 13:53
1

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

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever
    
ответ дан user545424 29.07.2014 в 15:51
1

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 包子露宪 六四事件 法轮功 28.05.2017 в 06:39