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


21

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

echo "something" > /path/foobar

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

Я пытался

sudo echo "something" > /path/foobar

но это не работает, потому что Суда только подсчитываю для editно не для правой части
из>

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

echo "something" | sudo tee /path/foobar

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

sudo !!

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



Это не дубликат. Я извлек настоящую Qeuration и изменил название. Теперь это то, что я действительно ищу
rubo77

Это, конечно, был дубликат, но сейчас это несколько иное. Мне кажется, что вы переписали вопрос в свете ответа Буги, и это хорошо - это хороший ответ. Я отказался от своего закрытого голосования, но оно все еще неизбежно (люди часто голосуют автоматически, когда вопрос находится в очереди закрытия, не обращая внимания на проблему): отправьте комментарий @goldilocks, когда он будет закрыт, и я проголосую, чтобы открыть его снова , Вы также можете заявить о своем случае в чате, как только это произойдет.
Златовласка

Ответы:


13

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

sudo bash -c !!

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

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 $BASH; $0работает только в том случае, если это абсолютный путь или когда он не содержит косой черты и путь поиска команд не изменился.
³ это псевдоним для ATT ksh, но это так же хорошо. fchist


9

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

echo "something">/path/file

Вы используете глобальный синтаксис замены, чтобы вызвать команду:

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

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

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


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

echo "something" | sudo tee myfile

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

Если вы хотите повторить команду и добавить текст в файл, у команды tee есть опция -a для добавления. Чтобы вы могли вспомнить команду с

sudo !!

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

пример:

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

хорошее решение, но немного трудно запомнить. Как я могу создать псевдоним для команды, используя !! вспомнить последнюю команду ?
rubo77

это -aдействительно необходимо? >перепишет файл, tee -aдобавит, что будет>>
rubo77

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

3
Если команда использовала кавычки, это не обязательно эквивалентно. Подумайте, echo "foo bar"что станет, sh -c "echo "foo bar""а что просто напечатать fooвместо foo bar.
Godlygeek

sudo sh -c '!!'Вместо этого я попытался, если ваша команда, но это тоже не работает
rubo77

Что если ваша команда использует одинарные и двойные кавычки? Или двойные кавычки и переменные расширения? Если пользователь сделал: a=bи тогда , echo "$a" >fileи тогда sudo sh -c '!!'она будет расширяться , sudo sh -c 'echo $a >file'которая будет печатать пустую строку вместо bв file.
Godlygeek

Так может быть, есть еще лучшее решение?
rubo77

1
Я не думаю, что есть какое-то решение, которое будет работать 100% времени без необходимости изменять команду. Использование sudoдля получения корневой оболочки, а затем копирование и вставка команды в нее было бы наиболее близким, но завершилось неудачно, если команда ожидала использования переменных, установленных в вашей некорневой оболочке. Использование sudo sh -c "!!"отлично работает для простых команд, но чревато сложными. Я думаю, что лучший совет - не ожидать, что есть какая-то команда, которая будет работать 100% времени, - изучить некоторые возможные решения и применять каждое из них, когда оно подходит лучше всего.
Godlygeek
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.