Ви не можете просто вставити sudo
перед командою оболонки, ви повинні викликати оболонку, щоб знову оцінити цю команду (виконуючи такі дії, як розширення змінних, відкриття файлів для операторів переадресації тощо). Так це
sudo bash -c !!
за винятком того, що це не зовсім працює, оскільки !!
інтерполює текст попередньої команди, спеціальні символи та все. Вам потрібно отримати текст команди у вигляді рядка і передати це як аргумент sh
. На щастя, fc
вбудований баш дозволяє вам це зробити¹.
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's $BASH
; $0
працює лише тоді, коли це абсолютний шлях або коли він не містить косою рисою і шлях пошуку команди не змінився.
³ псевдонім для ATT ksh, але це так само добре. fc
hist