Ad esempio, se voglio creare un file e inserire il testo in una riga, posso reindirizzare l'output in un file con l'uso di >
operatore:
echo "something" > /path/foobar
ma se non ho accesso alla cartella /path/
e ho bisogno dei privilegi sudo, come posso ottenere lo stesso comando di un normale utente con diritti sudo?
Ho provato
sudo echo "something" > /path/foobar
ma non funziona, perché sudo conta solo per edit
ma non per la parte destra
del >
Certo, potrei diventare root prima con sudo su
oppure usa tee
invece:
echo "something" | sudo tee /path/foobar
Ma vorrei trovare una soluzione in cui posso lavorare con l'ultima riga in sostituzione tramite
sudo !!
Non c'è un modo per "riciclare" l'ultima riga e aggiungere semplicemente sudo
davanti?
Risposta accettata:
Non puoi semplicemente attaccare sudo
prima di un comando di shell, devi invocare una shell per valutare nuovamente quel comando (facendo cose come espandere variabili, aprire file per operatori di reindirizzamento, ecc.). Quindi è
sudo bash -c !!
tranne per il fatto che questo non funziona, perché !!
interpola il testo del comando precedente, i caratteri speciali e tutto il resto. Devi recuperare il testo del comando come stringa e passarlo come argomento a sh
. Fortunatamente, fc
di bash builtin ti consente di farlo¹.
sudo bash -c "$(fc -ln -1)"
O anche, per essere sicuro di invocare la stessa versione di bash attualmente in esecuzione:
sudo "$BASH" -c "$(fc -ln -1)"
Nota che poiché il comando viene eseguito in un processo di shell separato, eredita le variabili di ambiente (solo quelle che sudo
conserva, mente), ma non le variabili interne della shell. Opzioni della shell (ad es. kshglob
) e anche altre impostazioni partiranno dal valore predefinito.
Lo stesso comando² funziona in zsh e ksh, sebbene ATT ksh93 richieda sia il first
e last
numero da passare a 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)"
Usando $0
designare l'eseguibile della shell in esecuzione funziona solo se la shell è stata invocata tramite $PATH e $PATH non è cambiato, o tramite un percorso assoluto.
Ecco un altro metodo in zsh che è leggermente più chiaro ma più lungo:
sudo zsh -c $history[$[HISTCMD-1]]
Un ultimo avvertimento:sudo
è per comandi potenzialmente pericolosi. Non renderlo troppo facile da usare!
¹ C'è qualche spazio extra all'inizio e la sostituzione del comando rimuove le nuove righe alla fine, ma la sintassi della shell non si preoccupa di questo.
² Non credo che zsh o ksh abbiano nulla di simile a $BASH
di bash; $0
funziona solo quando è un percorso assoluto o quando non contiene alcuna barra e il percorso di ricerca del comando non è cambiato.
³ fc
è un alias per hist
in ATT ksh ma è altrettanto buono.