Ви не можете просто вставити 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, але це так само добре. fchist