Например, если я хочу создать файл и ввести текст в одну строку, я могу перенаправить вывод в файл с помощью оператора >
:
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, но это так же хорошо. fc
hist
решение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