Esegui una riga di comandi con un sudo


21

Ad esempio, se voglio creare un file e inserire il testo in una riga, posso reindirizzare l'output in un file con l'uso >dell'operatore:

echo "something" > /path/foobar

ma se non ho accesso alla cartella /path/e ho bisogno di privilegi sudo, come posso ottenere lo stesso comando di un normale utente con diritti sudo?

Provai

sudo echo "something" > /path/foobar

ma questo non funziona, perché il sudo conta solo editper la parte giusta ma per
la>

Certo, potrei diventare root prima sudo suo usare teeinvece:

echo "something" | sudo tee /path/foobar

Ma vorrei trovare una soluzione in cui posso lavorare con l'ultima riga come sostituzione tramite

sudo !!

Non c'è un modo per "riciclare" l'ultima riga e aggiungere solo sudoin primo piano?



Questo non è un duplicato. Ho estratto la vera Qeustion e ho cambiato il titolo. Ora è quello che sto davvero cercando
rubo77,

Certamente era un duplicato, ma è un po 'diversa ora. Mi sembra che tu abbia riscritto la domanda alla luce della risposta di Boogy, che va bene - questa è una buona risposta. Ho ritirato il mio voto ravvicinato, ma è ancora inevitabile (le persone spesso votano automaticamente una volta che una domanda è in coda senza prestare attenzione al problema): rivolgi un commento a @goldilocks quando viene chiuso e voterò per riaprire . Puoi anche presentare il tuo caso in chat una volta che ciò accade.
Riccioli d'oro,

Risposte:


13

Non puoi semplicemente rimanere sudodavanti 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 fcbuilt-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 sudoconservano, 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 firste lastnumero 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 $0per 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; $0funziona 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. fchist


9

Se vuoi ripetere lo stesso comando con sudo !! dopo aver eseguito un comando come questo:

echo "something">/path/file

Si utilizza la sintassi di sostituzione globale per richiamare il comando:

!!:gs/>/|sudo tee -a /

Utilizzare uno spazio dopo il parametro -a .

Questo è l'equivalente di sudo !! ma ti aiuta a bypassare le restrizioni sudo per <e>. Perché sudo non ti consente di usare [<,>].


Per bypassare le restrizioni sudo in generale per i reindirizzamenti, puoi usarlo in questo modo:

echo "something" | sudo tee myfile

Il comando tee ti consentirà di leggere dallo standard input e di scrivere nello standard output e nei file

Se si desidera ripetere il comando e aggiungere un testo al file, il comando tee ha l' opzione -a per l'aggiunta. Quindi potresti richiamare il comando con

sudo !!

e il testo verrà aggiunto nel file

esempio:

echo "something" | sudo tee -a /path/file
sudo !!

bella soluzione, ma un po 'difficile da memorizzare. Come posso creare un alias per un comando usando !! richiamare l'ultimo comando ?
rubo77,

è -adavvero necessario? >sovrascriverà un file, tee -aaggiungerò, che sarebbe>>
rubo77

3

Sembra essere semplice come sudo sh -c "!!":

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

3
Se il comando utilizza virgolette, questo non è necessariamente equivalente. Considera echo "foo bar"quale diventerebbe sh -c "echo "foo bar""quale verrebbe stampato fooanziché foo bar.
godlygeek,

Ho provato sudo sh -c '!!'invece se il tuo comando ma non funziona neanche
rubo77

Quindi cosa succede se il tuo comando utilizza virgolette singole e doppie? O doppie virgolette ed espansioni variabili? Se l'utente lo facesse: a=be poi echo "$a" >filee poi sudo sh -c '!!'si espanderebbe su sudo sh -c 'echo $a >file'cui stampare una riga vuota anziché bin file.
godlygeek,

Quindi forse c'è una soluzione ancora migliore in qualche modo?
rubo77,

1
Non credo che ci sia alcuna soluzione che funzionerà il 100% delle volte senza che tu debba mai modificare il comando. L'uso sudoper ottenere una shell root e quindi la copia e incolla del comando in essa sarebbe il più vicino, ma fallisce se si prevede che il comando utilizzi le variabili impostate nella shell non root. L'uso sudo sh -c "!!"funziona bene per comandi semplici, ma è irto di comandi complessi. Penso che il miglior consiglio sia quello di non aspettarsi che ci sia qualche comando che funzionerà il 100% delle volte: impara alcune possibili soluzioni e applica ognuna quando meglio si adatta.
godlygeek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.