Come posso eseguire un comando sudo in Emacs?
Domanda
Sto cercando di creare tasti di scelta rapida per alcuni comandi della shell sudo comunemente usati (ad esempio, avere C-c s
correre (shell-command "sudo /etc/init.d/apache2 restart")
).
Ho provato a utilizzare una chiamata diretta al comando shell come sopra, ma restituisce semplicemente quanto segue al file *Shell Command Output*
respingente:
[sudo] password for Inaimathi:
Sorry, try again.
[sudo] password for Inaimathi:
Sorry, try again.
[sudo] password for Inaimathi:
Sorry, try again.
sudo: 3 incorrect password attempts
In realtà non richiede una password.Non voglio dover avviare Emacs utilizzando sudo emacs
, ma immagino che sia un'opzione se nient'altro funzionerà.
La soluzione ideale sarebbe una funzione interna a Emacs (in contrapposizione al sistema operativo jiggery-pokery per modificare il comportamento della shell o del sudo
comando).Qualcosa di simile a (sudo-shell-command "dostuff")
, O (with-password-prompt (shell-command "sudo dostuff"))
.
Soluzione
Come su:
(shell-command (concat "echo " (shell-quote-argument (read-passwd "Password? "))
" | sudo -S your_command_here"))
Altri suggerimenti
Chiamo spesso comandi da Emacs come aptitude update
. scottfrazerLa soluzione di potrebbe non essere altrettanto utile.I comandi sincroni mi fanno aspettare a lungo e se esegui un programma non supportato (ad esempio, aptitude
, che utilizza ncurses), riattaccherai Emacs (C-g non aiuterà) e il carico della CPU sarà al 100%.Modifica in async-shell-command
risolve questo.
Ma introduce anche un nuovo problema.Se il tuo comando fallisce, la tua password finirà in *Messages*
respingente:
echo PASSWORD | sudo -S aptitude: exited abnormally with code 1.
Ecco perchè propongo la seguente soluzione:
(defun sudo-shell-command (command)
(interactive "MShell command (root): ")
(with-temp-buffer
(cd "/sudo::/")
(async-shell-command command)))
Qui "M" dentro interactive
richiede il nome del programma nel minibuffer, with-temp-buffer
crea un buffer fittizio, in cui cambiamo la directory in /sudo::/
per utilizzare TRAMP per il prompt sudo.
Questa è la soluzione di David Kastrup di Comando sudo con richiesta password minibuffer @ gnu.emacs.help.
Nota, non dovresti comunque chiamare aptitude
direttamente, altrimenti il sottoprocesso sarà lì per sempre, fino all'invio sudo pkill aptitude
.
Continuare a leggere conchiglie E processi nel manuale.
Se stai usando emacs22 o poi, si può semplicemente avviare un guscio da emacs ed eseguire il comando sudo lì. Sarà si tira automaticamente nella finestra minibuffer per la password:
M-x shell
sudo whoami
Questo dovrebbe solo chiedere la password in basso nella parte inferiore dello schermo ( senza visualizzarlo).
Soluzione alternativa (piuttosto che una soluzione emacs):
Configura una coppia di chiavi ssh in modo che non sia necessaria alcuna password.
Procedura:
- correre
ssh-keygen
per generare una coppia di chiavi.Dai loro un nome utile per tenerli distinti da tutti gli altri che farai una volta che ti sarai abituato - Copia il pubblico uno a
$HOME/.ssh
per il ricevere account - Mantieni il privato uno in
$HOME/.ssh
dell'account di invio (potresti copiarlo su più account di invio, ma potrebbe essere meglio creare una coppia di chiavi separata per ogni macchina in entrata) - modificare
$HOME/.ssh/config
sulla macchina mittente per indicare a ssh quale chiave utilizzare - Profitto
sudo
tenta di aprire il dispositivo terminale (tty) per leggere la password. Il vostro processo di emacs non può avere un terminale di controllo. sudo -S
dice di usare lo standard input di una password che deve essere venuta da emacs.
EDIT: La risposta di Scott di cui sopra è di gran lunga preferibile a questo hack. Utilizzare tale.
Una possibile soluzione:
ho scoperto che l'impostazione di un programma di utilità di default password chiedendo risolve questo problema.
Quello che ho dovuto fare è aggiungere Defaults:ALL askpass=/usr/lib/openssh/gnome-ssh-askpass
al mio file /etc/sudoers
(usando sudo visudo
, ovviamente).
Eval-ing (shell-command "sudo /etc/init.d/apache2 restart")
ora mi chiede una password invece di cercare di indovinare senza successo.
Non sto ad accettare questa risposta se non diventa chiaro che non c'è soluzione migliore; Idealmente mi piacerebbe qualcosa che risolve il problema internamente per Emacs invece di richiedere di girare per la vostra directory /etc
.
Ho usato il seguente per iniziare nmap da emacs come root,