Non puoi semplicemente rimanere sudo
davanti a un comando di shell, devi invocare una shell per valutare di nuovo quel comando (fare cose come espandere variabili, aprire file per operatori di reindirizzamento, ecc.). Così è
sudo bash -c !!
tranne che questo non funziona del tutto, perché !!
interpola il testo del comando precedente, i caratteri speciali e tutto il resto. È necessario recuperare il testo del comando come stringa e passarlo come argomento a sh
. Fortunatamente, il fc
built-in di bash ti consente di farlo¹.
sudo bash -c "$(fc -ln -1)"
O anche, per essere sicuri di invocare la stessa versione di bash attualmente in esecuzione:
sudo "$BASH" -c "$(fc -ln -1)"
Si noti che poiché il comando viene eseguito in un processo di shell separato, eredita le variabili di ambiente (solo quelle che sudo
conservano, mente), ma non le variabili interne della shell. Le opzioni della shell (ad es. kshglob
) E altre impostazioni inizieranno anche dall'impostazione predefinita.
Lo stesso command² lavora in zsh e ksh, sebbene ATT ksh93 richiede sia il first
e last
numero da passare fc
³ (che funziona anche in bash, zsh e pdksh / mksh):
sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"
L'uso $0
per designare l'eseguibile della shell in esecuzione funziona solo se la shell è stata invocata attraverso $ PATH e $ PATH non è cambiata o attraverso un percorso assoluto.
Ecco un altro metodo in zsh che è leggermente più chiaro ma più lungo:
sudo zsh -c $history[$[HISTCMD-1]]
Un'ultima avvertenza: sudo
è per comandi potenzialmente pericolosi. Non renderlo troppo facile da usare!
¹ All'inizio c'è un po 'di spazio bianco in più e la sostituzione del comando rimuove le righe alla fine, ma la sintassi della shell non se ne preoccupa.
² Non credo che zsh o ksh abbiano qualcosa di simile a bash $BASH
; $0
funziona solo quando è un percorso assoluto o quando non contiene barra e il percorso di ricerca dei comandi non è cambiato.
³ è un alias per ATT ksh ma è altrettanto buono. fc
hist