Question

I'm trying to create shortcut keys for some commonly used sudo shell commands (for example, having C-c s run (shell-command "sudo /etc/init.d/apache2 restart")).

I tried using a straight-up shell-command call as above, but it just outputs the following to the *Shell Command Output* buffer:

[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

It doesn't actually ask for a password. I don't want to have to start up Emacs using sudo emacs, but I guess that's an option if nothing else will work.

The ideal solution would be a function from within Emacs (as opposed to OS jiggery-pokery to change the behaviour of the shell or the sudo command). Something like (sudo-shell-command "dostuff"), or (with-password-prompt (shell-command "sudo dostuff")).

Was it helpful?

Solution

How about:

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

OTHER TIPS

I frequently call commands from Emacs like aptitude update. scottfrazer's solution might not be as useful. Synchronous commands make me wait for a long time, and if you execute an unsupported program (for example, aptitude, which uses ncurses), you will hang up Emacs (C-g won't help), and CPU load will be 100%. Changing to async-shell-command solves this.

But it also introduces a new problem. If your command fails, your password will end up in *Messages* buffer:

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

That's why i propose the following solution:

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

Here "M" in interactive prompts for program name in minibuffer, with-temp-buffer creates a sham buffer, in which we change directory to /sudo::/ to use TRAMP for sudo prompt.

This is the solution by David Kastrup from sudo command with minibuffer password prompt @ gnu.emacs.help.

Note, you still shouldn't call aptitude directly, otherwise the subprocess will be there forever, until you send sudo pkill aptitude.

Read on shells and processes in manual.

If you're running emacs22 or later, you can just start up a shell from emacs and run your sudo command there. It'll automatically pull you into the minibuffer window for your password:

M-x shell
sudo whoami

This should just ask for your password down at the bottom of the screen (without displaying it).

Workaround (rather than an emacs solution):

Set up a ssh key pair so that no password is necessary.

Procedure:

  1. run ssh-keygen to generate a pair of keys. Give them a useful name to keep them sorted out from all the others you'll make once you get use to this
  2. Copy the public one to $HOME/.ssh for the receiving account
  3. Keep the private one in $HOME/.ssh of the sending account (you could copy it to multiple sending accounts, but it might be better to make a separate keypair for every incoming machine)
  4. edit $HOME/.ssh/config on the sending machine to tell ssh what key to use
  5. Profit

sudo attempts to open the terminal device (tty) to read the password. Your emacs process may not have a controlling terminal. sudo -S tells it to use the standard input for a password which should be coming from emacs.

EDIT: Scott's answer above is vastly preferable to this hack. Use that.

A possible solution:

I found out that setting a default password-asking utility solves this problem.

What I had to do is add Defaults:ALL askpass=/usr/lib/openssh/gnome-ssh-askpass to my /etc/sudoers file (using sudo visudo, obviously).

Eval-ing (shell-command "sudo /etc/init.d/apache2 restart") now prompts me for a password instead of trying to guess it unsuccessfully.

I'm not accepting this answer unless it becomes clear that there's no better solution; ideally I'd like something that solves the problem internally to Emacs instead of requiring you to poke around your /etc directory.

I used the following to start nmap from emacs as root,

http://nakkaya.com/sudoEl.markdown

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top