Выполнить строку команд с помощью одного sudo

Выполнить строку команд с помощью одного sudo

Например, если я хочу создать файл и ввести текст в одну строку, я могу перенаправить вывод в файл с помощью оператора >:

echo "something" > /path/foobar

Но если у меня нет доступа к папке /path/и мне нужны привилегии sudo, как я могу выполнить эту же команду как обычный пользователь с правами sudo?

Я пытался

sudo echo "something" > /path/foobar

но это не работает, потому что sudo учитывает только правую часть edit, а не правую.
>

Конечно, я мог бы получить права root раньше sudo suили использовать teeвместо этого:

echo "something" | sudo tee /path/foobar

Но я хотел бы найти решение, где я мог бы работать с последней строкой в ​​качестве замены через

sudo !!

Разве нет способа «переработать» последнюю строку и просто добавить ее sudoв начало?

решение1

Вы не можете просто вставить sudoкоманду оболочки, вам придется вызывать оболочку, чтобы снова выполнить эту команду (выполняя такие действия, как расширение переменных, открытие файлов для операторов перенаправления и т. д.). Так вот

sudo bash -c !!

за исключением того, что это не совсем работает, потому что !!интерполирует текст предыдущей команды, специальные символы и все такое. Вам нужно получить текст команды как строку и передать его как аргумент в sh. К счастью, bashfcвстроенныйпозволяет вам это сделать¹.

sudo bash -c "$(fc -ln -1)"

Или даже, чтобы убедиться, что вы вызываете ту же версию bash, которая запущена в данный момент:

sudo "$BASH" -c "$(fc -ln -1)"

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

Та же команда² работает в zsh и ksh, хотя ATT ksh93 требует, чтобы и firstчисло, и ³ lastбыли переданы в fc³ (что также работает в bash, zsh и pdksh/mksh):

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

Использование $0для обозначения исполняемого файла запущенной оболочки работает только в том случае, если оболочка была вызвана через $PATH и $PATH не изменился или через абсолютный путь.

Вот еще один метод в zsh, который немного понятнее, но длиннее:

sudo zsh -c $history[$[HISTCMD-1]]

Последнее слово предупреждения: sudoдля потенциально опасных команд. Не упрощайте его использование!

¹ В начале есть несколько дополнительных пробелов, а подстановка команд убирает переводы строк в конце, но синтаксис оболочки не обращает на это внимания.
² Я не думаю, что в zsh или ksh есть что-то похожее на $BASH; $0работает только когда это абсолютный путь или когда он не содержит слеша и путь поиска команд не изменился.
³ — это псевдоним для в ATT ksh, но это так же хорошо. fchist

решение2

Если вы хотите повторить ту же команду с помощьюсудо!!после выполнения такой команды:

echo "something">/path/file

Затем вы используете глобальный синтаксис замены для повторного вызова команды:

!!:gs/>/|sudo tee -a /

Используйте пробел послепараметр.

Это эквивалентносудо!!но помогает обойти ограничения sudo для < и >. Поскольку sudo не позволяет использовать [<, >].


Чтобы обойти ограничения sudo в целом для перенаправлений, вы можете использовать это следующим образом:

echo "something" | sudo tee myfile

Команда tee позволит вам читать из стандартного ввода и записывать в стандартный вывод и файлы.

Если вы хотите повторить команду и добавить текст в файл, команда tee имеетвариант для добавления. Таким образом, вы можете вызвать команду с помощью

sudo !!

и текст будет добавлен в файл

пример:

echo "something" | sudo tee -a /path/file
sudo !!

решение3

Кажется, это так просто sudo sh -c "!!":

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

Связанный контент