2010-03-18 9 views
13

Estoy tratando de crear teclas de acceso directo para algunos comandos de sudo shell de uso común (por ejemplo, tener C-c s ejecutar (shell-command "sudo /etc/init.d/apache2 restart")).¿Cómo ejecuto un comando sudo en Emacs?

He intentado utilizar una llamada shell-command recto-para arriba que el anterior, pero simplemente muestra la siguiente información a la memoria intermedia *Shell Command Output*:

[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 

En realidad, no pide una contraseña. No quiero tener que iniciar Emacs usando sudo emacs, pero supongo que es una opción si nada más va a funcionar.

La solución ideal sería una función desde Emacs (en oposición a OS jiggery-pokery para cambiar el comportamiento del shell o el comando sudo). Algo así como (sudo-shell-command "dostuff") o (with-password-prompt (shell-command "sudo dostuff")).

+0

Relacionado (¿casi duplicado?): Http://stackoverflow.com/questions/95631/open-a-file-with-su-sudo-inside-emacs y el voto para migrar a Super User puede ser correcto. @Inaimathi: si esto está estrechamente relacionado con la programación, ahora sería un buen momento para explicar por qué, o estas preguntas probablemente se trasladarán a un sitio más adecuado. – dmckee

+2

Dado que OP está intentando vincular alguna elisp a una clave, esto es lo suficientemente programmymy para mí. – dmckee

+0

Pregunta reestructurada para aliviar parte de la confusión. – Inaimathi

Respuesta

13

¿Qué tal:

(shell-command (concat "echo " (shell-quote-argument (read-passwd "Password? ")) 
         " | sudo -S your_command_here")) 
+0

Perfecto. En otras palabras, podría hacer algo como '(defun sudo-shell-command (comando) (shell-command (concat" echo "(read-passwd" Password: ")" | sudo -S "))' . Mucho mejor que escribir la contraseña en el código fuente también. – Inaimathi

3

Si está ejecutando emacs22 o posterior, puede simplemente iniciar un shell desde emacs y ejecutar allí su comando sudo. Esto te tire automáticamente en la ventana de minibúfer para su contraseña:

M-x shell 
sudo whoami 

Esto sólo debe pedir su contraseña abajo en la parte inferior de la pantalla (sin mostrarlo).

+0

eshell también es bueno :) – rmk

+0

Prefiero 'ansi-term';) –

1

sudo intenta abrir el dispositivo terminal (tty) para leer la contraseña. Es posible que su proceso de emacs no tenga una terminal de control. sudo -S le dice que use la entrada estándar para una contraseña que debería provenir de emacs.

+0

' (shell-command "sudo -S /etc/init.d/apache2 restart") 'hace lo mismo (es decir, trata de una forma arbitraria contraseña 3 veces, y envía los 3 intentos fallidos al búfer '* Shell Command Output *'. – Inaimathi

+0

Y '(shell-command" echo password | sudo -S /etc/init.d/apache2 restart ")'? (Not que es una buena solución para codificar la contraseña en el comando.) –

+0

Sí. No me gustaría que mi contraseña de root esté en mi código en alguna parte. Parece que podría ser peor que ejecutar 'sudo emacs'. +1 por sugerir el enfoque -S (incluso si no entendí bien al principio) – Inaimathi

1

EDITAR: La respuesta de Scott anterior es muy preferible a este truco. Usa eso.

Una posible solución:

descubrí que el establecimiento de una utilidad de pedir contraseña por defecto resuelve este problema.

Lo que tuve que hacer es agregar Defaults:ALL askpass=/usr/lib/openssh/gnome-ssh-askpass a mi archivo /etc/sudoers (usando sudo visudo, obviamente).

Evaluar (shell-command "sudo /etc/init.d/apache2 restart") ahora me pide una contraseña en lugar de tratar de adivinarla sin éxito.

No acepto esta respuesta a menos que quede claro que no hay mejor solución; idealmente, me gustaría algo que resuelva el problema internamente de Emacs en lugar de requerirle que hurgue en su directorio /etc.

+0

Mejor aún, si tiene control de sudoers, puede configurarlo para que * usted * no se le solicite una contraseña para estos programas que ejecuta con frecuencia . –

3

Solución (en lugar de una solución emacs):

Establecer un par de claves SSH para que ninguna contraseña es necesaria.

Procedimiento:

  1. ssh-keygen plazo para generar un par de claves.darles un nombre útil para mantenerlos ordenados hacia fuera de todos los demás que va a hacer una vez que llegue a utilizar este
  2. Copiar el público uno a $HOME/.ssh para la recepción de cuenta
  3. Mantenga el privada uno en $HOME/.ssh de la cuenta que se envía (se puede copiar a múltiples cuentas de origen, pero podría ser mejor hacer un par de claves por separado para cada máquina entrante)
  4. edición $HOME/.ssh/config en la máquina de envío de decir ssh lo tecla para usar
  5. Beneficio
0

que utiliza lo siguiente para iniciar nmap desde emacs como root,

http://nakkaya.com/sudoEl.markdown

+0

Ese enlace parece estar muerto. ¿Hay algún lugar donde podamos verlo? –

11

frecuencia lo llamo comandos de Emacs como aptitude update. La solución de scottfrazer puede no ser tan útil. Los comandos sincrónicos me hacen esperar mucho tiempo, y si ejecuta un programa no compatible (por ejemplo, aptitude, que usa ncurses), colgará Emacs (Cg no ayudará) y la carga de la CPU será del 100% . Cambiar a async-shell-command resuelve esto.

Pero también presenta un nuevo problema. Si el comando falla, su contraseña va a terminar en *Messages* búfer:

echo PASSWORD | sudo -S aptitude: exited abnormally with code 1. 

Es por eso que propongo la siguiente solución:

(defun sudo-shell-command (command) 
    (interactive "MShell command (root): ") 
    (with-temp-buffer 
    (cd "/sudo::/") 
    (async-shell-command command))) 

aquí "M" en interactive solicita el nombre del programa en minibuffer, with-temp-buffer crea un búfer simulado, en el cual cambiamos el directorio a /sudo::/ para usar TRAMP para el prompt de sudo.

Esta es la solución de David Kastrup de sudo command with minibuffer password prompt @ gnu.emacs.help.

Tenga en cuenta que todavía no debe llamar al aptitude directamente, de lo contrario el subproceso estará allí para siempre, hasta que envíe sudo pkill aptitude.

Lea en shells y processes en el manual.

+1

Gracias, su respuesta es exactamente lo que estaba buscando. Creo que debería estar marcado como el mejor. –

Cuestiones relacionadas