如何在 Emacs 中运行 sudo 命令?

Posted

技术标签:

【中文标题】如何在 Emacs 中运行 sudo 命令?【英文标题】:How do I run a sudo command in Emacs? 【发布时间】:2011-01-29 03:50:00 【问题描述】:

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

我尝试使用上述的直接 shell 命令调用,但它只是将以下内容输出到 *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"))

【问题讨论】:

相关(几乎重复?):***.com/questions/95631/… 并且对迁移到超级用户的投票可能是正确的。 @Inaimathi:如果这与编程密切相关,现在是解释原因的好时机,或者这个问题可能会转移到更合适的网站。 鉴于 OP 试图将一些 elisp 绑定到一个键,这对我来说已经足够编程了。 重组问题以减轻一些混乱。 你不用这个。您可以使用 TRAMP,/sudo::/etc/init.d/apaches2 打开文件,然后使用 M-x shell 从该文件启动 shell。 【参考方案1】:

我经常从 Emacs 调用命令,例如 aptitude update。 scottfrazer 的解决方案可能没有那么有用。同步命令让我等了很久,如果你执行了一个不受支持的程序(比如aptitude,它使用了ncurses),你会挂掉Emacs(Cg 无济于事),CPU 负载将为 100%。更改为 async-shell-command 即可解决此问题。

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

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

这就是我提出以下解决方案的原因:

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

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

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

注意,你仍然不应该直接调用aptitude,否则子进程将永远存在,直到你发送sudo pkill aptitude

阅读手册中的shells 和processes。

【讨论】:

谢谢,您的回答正是我想要的。我认为它应该被标记为最好的。【参考方案2】:

怎么样:

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

【讨论】:

完美。换句话说,我可以轻松地做类似(defun sudo-shell-command (command) (shell-command (concat "echo " (read-passwd "Password: ") " | sudo -S " command))) 的事情。也比在源代码中实际编写密码要好得多。【参考方案3】:

编辑:斯科特上面的回答比这个黑客更可取。使用它。

一个可能的解决方案:

我发现设置一个默认的密码询问实用程序可以解决这个问题。

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

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

除非很明显没有更好的解决方案,否则我不会接受这个答案;理想情况下,我想要一些可以在 Emacs 内部解决问题的东西,而不是要求您在 /etc 目录中四处寻找。

【讨论】:

更好的是,如果你有 sudoers 控制,你可以设置它,这样 就不会被提示输入你经常运行的这些程序的密码。【参考方案4】:

我使用以下命令从 emacs 以 root 身份启动 nmap,

http://nakkaya.com/sudoEl.markdown

【讨论】:

该链接似乎已失效。有什么地方可以看到吗?【参考方案5】:

解决方法(而不是 emacs 解决方案):

设置一个 ssh 密钥对,这样就不需要密码了。

程序:

    运行ssh-keygen 生成一对密钥。给它们起一个有用的名称,以便在您习惯后将它们与您将要创建的所有其他名称区分开来 将public一复制到$HOME/.ssh接收帐户 将私有一个保存在发送帐户的$HOME/.ssh 中(您可以将其复制到多个发送帐户,但最好为每台传入机器制作单独的密钥对) 在发送机器上编辑$HOME/.ssh/config 告诉 ssh 使用什么密钥 利润

【讨论】:

【参考方案6】:

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

【讨论】:

(shell-command "sudo -S /etc/init.d/apache2 restart") 做同样的事情(即,它尝试任意密码 3 次,并将 3 次不成功的尝试发送到 *Shell Command Output* 缓冲区。 还有(shell-command "echo password | sudo -S /etc/init.d/apache2 restart")? (并不是说在命令中对密码进行编码是一个很好的解决方案。) 是的。我不希望在我的代码中的某个地方使用我的 root 密码。这听起来可能比运行sudo emacs 更糟糕。 +1 建议使用 -S 方法(即使我一开始确实误解了它)【参考方案7】:

如果你运行的是 emacs22 或更高版本,你可以从 emacs 启动一个 shell 并在那里运行你的 sudo 命令。它会自动将您拉入迷你缓冲区窗口以获取您的密码:

M-x shell
sudo whoami

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

【讨论】:

这是最简单的解决方案。谢谢。

以上是关于如何在 Emacs 中运行 sudo 命令?的主要内容,如果未能解决你的问题,请参考以下文章

sudo如何在Ubuntu上使用Emacs编辑本地文件?

如何在 ubuntu 上的 emacs 中运行 shell 命令,同时避免 bash 作业控制错误?

emacs中解释器中的命令历史记录

如何在没有 sudo 的 Perl 中运行命令?

如何在 Emacs 中运行 Cygwin Bash Shell?

Linux系统技巧|对于Linux系统管理员有用的 sudoers 配置|如何配置 sudo 命令在运行时而不输入密码