Вы не можете просто вставлять 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, но это так же хорошо. fc
hist