How do I run a sudo command in Emacs?

2020-07-03 04:04发布

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")).

标签: emacs sudo shell
7条回答
一夜七次
2楼-- · 2020-07-03 04:33

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.

查看更多
爷、活的狠高调
3楼-- · 2020-07-03 04:39

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).

查看更多
The star\"
4楼-- · 2020-07-03 04:40

How about:

(shell-command (concat "echo " (shell-quote-argument (read-passwd "Password? "))
                       " | sudo -S your_command_here"))
查看更多
手持菜刀,她持情操
5楼-- · 2020-07-03 04:41

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
查看更多
仙女界的扛把子
6楼-- · 2020-07-03 04:41

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

http://nakkaya.com/sudoEl.markdown

查看更多
疯言疯语
7楼-- · 2020-07-03 04:49

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.

查看更多
登录 后发表回答