Вопрос или проблема
Я пытаюсь следовать тому, что, как я предполагаю, является лучшими практиками использования sudo вместо учетной записи root.
Я выполняю простую операцию конкатенации файла, такую как:
sudo echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock
Это не удается, поскольку справа от “>>” выполняется команда от имени обычного пользователя. Добавление дополнительных sudo также не удается (ожидаемое поведение, так как команда направляется в sudo, а не в файл).
Этот пример проверен и протестирован под учетной записью root.
Вы можете вызвать новую оболочку как root:
sudo sh -c 'echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'
Вы также можете просто повысить права процесса, чтобы записывать в файл:
sudo tee -a /etc/conf.d/hwclock > /dev/null << EOF
clock_hctosys="YES"
EOF
Другой вариант, не менее безопасный, – использовать переключатель -i
команды sudo
, чтобы войти как root:
$ sudo -i
# echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'
Это все равно соответствует правилам лучших практик, поскольку учетная запись root фактически не активируется, а позволяет безопасно выполнять действия от имени root. Из man sudo
:
Опция -i (симуляция первоначального входа) запускает оболочку,
указанную записью базы данных паролей целевого пользователя,
как логин-оболочку. Это означает, что файлы ресурсов,
специфичные для логина, такие как .profile или .login, будут
прочитаны оболочкой. Если команда указана, она передается
оболочке для выполнения через опцию -c оболочки. Если команда
не указана, запускается интерактивная оболочка.
sudo dd of=
Чтобы добавить, как с помощью >>
:
echo inbytes | sudo dd of=path/to/outfile oflag=append conv=notrunc
или чтобы воссоздать файл с нуля, как с помощью >
:
echo inbytes | sudo dd of=path/to/outfile
Кроме того, можно сделать dd
более тихим с помощью status=none
, как в:
echo inbytes | sudo dd of=path/to/outfile status=none
иначе он выводит некоторую информацию о состоянии типа:
0+1 записей прочитано
0+1 записей записано
8 байт скопировано, 2.7432e-05 с, 292 кБ/с
Альтернативно, можно также сделать более подробным и наблюдать скорость передачи с status=progress
, как я упомянул в этом другом ответе.
Преимущества:
- удобнее, чем
tee
, так как нет перенаправления/dev/null
- удобнее, чем
sh
, так как нет подсистемы dd
имеет много мощных опций, например,status=progress
для отображения хода передачи
Работает, потому что sudo перенаправляет стандартный ввод на команду.
Если выразить команду без одинарных кавычек, ее можно поместить внутрь одинарных кавычек и выполнить через промежуточную оболочку.
Чтобы выполнить это как root:
echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock
Запишите команду по-другому, чтобы не использовать '
:
echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock
Затем вызовите sudo sh -c …
:
sudo sh -c 'echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'
Альтернативно, чтобы записать вывод в файл, в который может записывать только root, вызовите sudo tee
. Передайте опцию -a
для tee
, чтобы добавить в файл назначения, в противном случае файл будет усечен.
echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock >/dev/null
Для более сложных модификаций файла можно вызвать sudo sed
, sudo ed
, sudo perl
и т.д.
Или используйте приличный редактор и заставьте его вызвать sudo. В Emacs откройте /sudo:/etc/conf.d/hwclock
. В Vim вызовите :w !sudo tee %
, чтобы записать в открытый файл как root, или используйте плагин sudo.vim. Или войдите в систему через sudo и вызовите sudoedit /etc/conf.d/hwclock
.
Или можно уступить на темной стороне и запустить оболочку как root.
$ sudo -i
# echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock
Команда не выполняется из-за разрешений на файл, в который происходит перенаправление. Перенаправление происходит еще до того, как вызывается команда sudo
.
Вы должны убедиться, что именно root открывает файл для записи.
Самый простой способ сделать это:
echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock >/dev/null
Команда echo
может быть выполнена обычным пользователем, так как она просто генерирует текстовую строку. Тем не менее, утилита tee
должна выполняться от имени root, причем tee -a
добавит данные. Мы перенаправляем вывод в /dev/null
, поскольку tee
по умолчанию дублирует свой ввод на стандартный вывод помимо записи в указанные файлы.
С помощью bash
или любой оболочки, которая понимает “строки”:
sudo tee -a /etc/conf.d/hwclock >/dev/null <<<'clock_hctosys="YES"'
Это идентично вышеуказанному. Единственное изменение – способ генерации строки.
Другой, слегка обходной способ сделать это:
sudo sh -c 'echo clock_hctosys=\"YES\" >>/etc/conf.d/hwclock'
Здесь перенаправление происходит в sh -c
дочерней оболочке, выполняющейся как root.
Или дать строку для добавления как аргумент оболочке sh -c
, выполняемой как root:
sudo sh -c 'printf "%s\n" "$1" >>/etc/conf.d/hwclock' sh 'clock_hctosys="YES"'
… что может быть обобщено для добавления всех аргументов как строк в файл:
set -- 'строка 1' 'строка 2' 'строка 3'
sudo sh -c 'printf "%s\n" "$@" >>/etc/conf.d/hwclock' sh "$@"
Удивительно, как редко этот инструмент упоминается, учитывая, насколько он полезен:
sponge
из пакета moreutils
. Он доступен практически в каждом дистрибутиве под тем же именем и может справляться с множеством ситуаций, с которыми оболочка плохо справляется.
Изначально его предназначение – позволить сначала прочитать, а затем записать обратно в тот же файл (что оболочка не может, потому что перенаправление обрабатывается первым). Тем не менее, он также отлично подходит для этой цели:
echo "hello world" | sudo sponge /path/to/privileged/file
Все просто. А если нужно добавить вместо перезаписывания (>>
), есть флаг -a
.
Посмотрите руководство.
.
Ответ или решение
В ситуациях, когда вы работаете в операционных системах на базе Unix или Linux, нередко возникает необходимость выполнять команды с привилегированным доступом, особенно при работе с файлами и каталогами, доступ к которым ограничен. Одним из лучших решений для этого является использование команды sudo
, которая позволяет временно получать права суперпользователя для выполнения определенных команд. Однако, есть определенные сложности, когда речь идет о перенаправлении вывода или использовании конвейеров (пайпов) с sudo
, так как стандартное перенаправление и пайпинг выполняются оболочкой, а не командой.
Теория
Основная проблема возникает из-за того, что когда используется перенаправление с помощью >
или >>
, это перенаправление обрабатывается самой оболочкой, а не командой sudo
. То есть, команда sudo
предоставляет привилегии только для выполнения указанной команды, но не для перенаправления вывода, которое по-прежнему выполняется с правами текущего пользователя. Это приводит к ошибкам доступа при попытке записать данные в файлы, принадлежащие root-пользователю.
Пример
Рассмотрим пример использования команды sudo
с перенаправлением:
sudo echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock
Эта команда не выполнится успешно, так как echo
отрабатывает с правами root, но перенаправление >>
все еще выполняется от имени обычного пользователя. В результате мы получаем ошибку доступа.
Применение
Есть несколько методов, позволяющих корректно выполнять такие операции, используя sudo
без прямого входа в систему под root.
-
Использование оболочки
sh -c
:Один из самых простых способов заключается в запуске новой командной оболочки от имени root, и выполнение всей команды в этой оболочке:
sudo sh -c 'echo clock_hctosys="YES" >> /etc/conf.d/hwclock'
Здесь вся строка, включая перенаправление, выполняется в привилегированной оболочке, что решает проблему доступа.
-
Команда
tee
:tee
— это утилита, которая может считывать ввод из стандартного потока и записывать его в несколько файлов, не разрывая поток, и она может быть использована для записи в файлы с правами суперпользователя:echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock > /dev/null
Здесь
-a
указывает на добавление в файл, а не перезапись, а выходtee
перенаправляется в/dev/null
, чтобы не отображать результаты. -
Пакет
moreutils
и утилитаsponge
:Утилита
sponge
, доступная в пакетеmoreutils
, предлагает другой подход, позволяющий сначала полностью считывать ввод перед записью:echo 'clock_hctosys="YES"' | sudo sponge /etc/conf.d/hwclock
Использование
-a
сsponge
позволяет дописывать в файл, как и при использовании>>
.
Это лишь несколько способов правильно использовать sudo
для операций с перенаправлением. Важно помнить, что каждое решение должно быть выбрано в зависимости от контекста задачи и специфики работы.
Вне зависимости от выбранного метода, важно убедиться в безопасности и корректности выполняемых команд, следя за правами доступа и подтверждая необходимость выполнения тех или иных операций с повышенными привилегиями.