2010-03-18 250 views
13

我试图为一些常用的sudo shell命令创建快捷键(例如,有C-c s运行(shell-command "sudo /etc/init.d/apache2 restart"))。如何在Emacs中运行sudo命令?

我试着使用上述直了壳命令调用,但它只是输出以下为*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 

实际上它并不要求提供密码。我不想使用sudo emacs启动Emacs,但我想这是一个选项,如果没有其他的工作。

理想的解决方案是Emacs中的一个函数(与OS Jiggery-pokery相反,用于更改shell或sudo命令的行为)。类似于(sudo-shell-command "dostuff")(with-password-prompt (shell-command "sudo dostuff"))

+0

相关(近似重复?):http://stackoverflow.com/questions/95631/open-a-file-with-su-sudo-inside-emacs和投票迁移到超级用户可能是正确的。 @Inaimathi:如果这与编程密切相关,现在是解释原因的好时机,否则这些问题可能会转移到更适合的地方。 – dmckee 2010-03-18 18:25:58

+2

鉴于OP正试图将某个elisp绑定到某个密钥,这对我来说足够程序化。 – dmckee 2010-03-18 18:34:18

+0

调整问题以缓解一些混乱。 – Inaimathi 2010-03-18 19:21:42

回答

13

如何:

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

完美。换句话说,我可以很容易地做类似'(defun sudo-shell-command(command)(shell-command(concat“echo”(read-passwd“Password:”)“| sudo -S”command) 。比在源代码中实际编写密码要好得多。 – Inaimathi 2010-03-18 21:07:30

3

如果您正在运行emacs22或更高版本,您可以从emacs启动一个shell并在其中运行sudo命令。它会自动把你拉进小缓冲区窗口输入密码:

M-x shell 
sudo whoami 

这应该只是询问您的密码倒在屏幕的底部(没有显示它)。

+0

eshell也不错:) – rmk 2010-03-18 18:17:39

+0

我更喜欢'ansi-term';) – 2010-12-19 11:28:25

1

sudo尝试打开终端设备(tty)以读取密码。您的emacs进程可能没有控制终端。 sudo -S告诉它使用标准输入来输入应该来自emacs的密码。

+0

'(shell-command“sudo -S /etc/init.d/apache2 restart”)'做同样的事情(即它尝试一个任意的密码3次,然后将3次不成功的尝试发送到'* Shell Command Output *'缓冲区。 – Inaimathi 2010-03-18 18:47:08

+0

和'(shell-command“echo password | sudo -S /etc/init.d/apache2 restart))??在命令中编码密码是一个很好的解决方案。) – 2010-03-18 19:55:48

+0

是的。我不希望我的密码在我的代码中。这听起来像可能比运行'sudo emacs'更糟糕。 +1用于提示-S方法(即使我起初误解了它) – Inaimathi 2010-03-18 21:10:27

1

编辑:斯科特的上面的答案是远远优于此黑客。使用它。

一个可能的解决方案:

我发现,设置默认密码要求公用事业解决了这个问题。

我所要做的就是将Defaults:ALL askpass=/usr/lib/openssh/gnome-ssh-askpass添加到我的/etc/sudoers文件(显然,使用sudo visudo)。

评估(shell-command "sudo /etc/init.d/apache2 restart")现在提示我输入密码,而不是尝试猜测它失败。

我不接受这个答案,除非明确表示没有更好的解决方案;理想情况下,我希望能够解决Emacs内部问题的某些内容,而不是要求您在/etc目录中徘徊。

+0

更好的是,如果您有sudoers控件,则可以将其设置为* *您不会为频繁运行的这些程序提示输入密码。 – 2010-03-18 19:50:57

3

解决方法(而不是一个emacs的溶液):

设置一个SSH密钥对,使得没有密码是必要的。

步骤:

  1. 运行ssh-keygen以产生一对密钥。给他们一个有用的名字,让他们与所有其他整理出来,一旦你使用这个
  2. 复制公共一个$HOME/.ssh接收帐户
  3. 保持私人一个你会成功在发送账号$HOME/.ssh(你可以把它复制到多个发送帐户,但它可能是更好地使每一个进入的机器单独密钥对)
  4. 编辑$HOME/.ssh/config发送机器上告诉ssh来使用什么键
  5. 利润
0

我用下面从emacs的作为根NMAP开始,

http://nakkaya.com/sudoEl.markdown

+0

该链接似乎死亡。有什么地方我们可以看到它吗? – 2013-05-16 01:59:02

11

我经常调用命令,从Emacs的像aptitude updatescottfrazer的解决方案可能没有那么有用。同步命令让我等了很长时间,如果你执行一个不支持的程序(例如,​​,它使用ncurses),你会挂断Emacs(Cg不会帮助),CPU负载将是100% 。改为async-shell-command解决了这个问题。

但它也引入了一个新问题。如果你的命令失败,您的密码将在*Messages*缓冲结束:

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

这就是为什么我提出以下解决方案:在interactive

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

这里的“M”在迷你缓冲区中提示输入程序名称,with-temp-buffer创建一个假缓冲区,其中我们将目录更改为/sudo::/以使用TRAMP作为sudo提示符。

这是David Kastrup从sudo command with minibuffer password prompt @ gnu.emacs.help得到的解决方案。

请注意,您仍然不应直接拨打​​,否则子进程将永远存在,直到您发送sudo pkill aptitude

阅读shellsprocesses手册。

+1

谢谢,你的答案正是我正在寻找的。我认为它应该被标记为最好的。 – 2014-10-03 08:38:11