BASH Tips&Tricks #0003: Запись stdin в файл под sudo

BASH
С утилитой sudo есть одна маленькая, но весьма досадная проблема: она, конечно, исполнит указанную команду под каким угодно пользователем и может сделать это даже тихо и незаметно, без ввода пароля, но вот перенаправление ввода-вывода будет отрабатывать уже под обычным пользователем.
Возникла у меня задачка: нужно записать строчку /opt/OpenLDAP/current/Binaries/lib в файл /etc/ld.so.conf.d/OpenLDAP.conf — с целью, понятное дело, вполне тривиальной: заставить систему читать библиотеки OpenLDAP оттуда, откуда нужно мне, а не ей.

Итак, давайте сделаем вид, что мы наивные и попробуем поступить прямолинейно:
sudo echo '/opt/OpenLDAP/current/Binaries/lib' > /etc/ld.so.conf.d/OpenLDAP.conf
Опа! Permission denied, кто бы мог подумать :)

Ну что же, шутки в сторону: есть у нас в запасе и свой каменный цветок. Речь идёт о конструкции <(команда), которая создаёт анонимный файловый дескриптор и записывает туда вывод команды. Попробуйте, например, сделать echo <(echo 'Hello, world!') — что вы видите? Правильно, это путь к файлу устройства, на момент исполнения команды содержащего заветную строчку, печатью коей на терминал, а то и в msgbox'ы, начиналась карьера величайших программистов мира.
Давайте же, не мешкая, используем полученное нами сакральное знание во благо:
sudo cp <(echo '/opt/OpenLDAP/current/Binaries/lib') /etc/ld.so.conf.d/OpenLDAP.conf

Раз уж мы вспомнили о файлах устройств, то есть и yet another вариант — он более универсален и, быть может, понравится вам больше:
sudo cp /dev/stdin /etc/ld.so.conf.d/OpenLDAP.conf <<<'/opt/OpenLDAP/current/Binaries/lib'
Кстати, в качестве домашнего задания к этому уроку предлагаю почитать о конструкции "<<<" в man bash.
Стоп! После всех этих высушивающих мозг конструкций вас наверняка потянуло к заварочному чайнику: ведь так хочется насладиться свежезаваренным зелёным gun powder после трудного рабочего дня. Ну конечно же, вот и она, наша классика жанра!
sudo tee /etc/ld.so.conf.d/OpenLDAP.conf <<<'/opt/OpenLDAP/current/Binaries/lib'>/dev/null


Ok, но как же быть, если требуется не создать новый файл, а всего лишь дополнить существующий?

Для частного случая добавления одной строки в конец файла вполне подойдёт старый-добрый sed, который мы все так любим:
sudo sed -i '$a\строка' файл


Но, разумеется, есть и путь настоящего самурая — так называемый «чайный» метод (и неважно, что tea — это не tee, да и tee вовсе не для того создавалась):
sudo tee -a короткая_речь_маленького_человека.txt <<<'Я не буду говорить долго, я буду говорить коротко'>/dev/null


Вот, пожалуй, и все хорошо известные и плохо скрываемые секреты языка программирования BASH, о которых я хотел сегодня вам поведать.
До новых встреч!

3 комментария

avatar
В избранное
avatar
Дэвид Блейн, ты демон, Дэвид Блейн
avatar
Поскольку главной радости в жизни — велосипеда и путешествий на своих двоих, меня лишили, а иные сильные мотивации вероятно как-то поддерживались здоровой физической активностью… я уже настолько тронулся умом, что посмотрел шоу Девида Блейна с пародийным переводом. И даже посмеялся.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.