Emacs 调用进程为 sudo

Jac*_*ers 2 emacs sudo elisp

更新

我已经接受了@Sean 的回答,并做了一些小的修改。

(defun sudo-shell-command (buffer password command)
  (let ((proc (start-process-shell-command
           "*sudo*"
           buffer
           (concat "sudo bash -c "
                   (shell-quote-argument command)))))
    ;;; Added to @Sean answer to display the passed buffer
    (display-buffer buffer '((display-buffer . nil)) nil)
    (process-send-string proc password)
    (process-send-string proc "\r")
    (process-send-eof proc)))

(defun sudo-bundle-install (password)
  (interactive (list (read-passwd "Sudo password for bundle install: ")))
  (let ((default-directory (concat default-directory
                               "./fixtures/test-kitchen-mode-test-run/"))
    ;;; Added from accepted answer below by @sean
    ;;; need a buffer to display process in.
    (generated-buffer (generate-new-buffer "*test-kitchen-test-setup*")))
    (sudo-shell-command
      ;;; pass reference to generated process buffer by name.
      ;;; Need to add a defun to get the current test-kitchen buffer 
      ;;; if it exists to use, but that is outside the scope of the question.
      (buffer-name generated-buffer)
      password
      "bundle install; bundle exec berks install")
    (clear-string password)))
Run Code Online (Sandbox Code Playgroud)

假设我需要在 elisp 中调用一个进程,并且该进程需要 sudo 权限。例如,运行 Ruby 的bundle install:

(let ((generated-buffer (generate-new-buffer "*test-kitchen-test-setup*")))
  (display-buffer generated-buffer '((display-buffer . nil)) nil)
  (call-process-shell-command
    (concat "cd " (concat default-directory "./fixtures/test-kitchen-mode-test-run") 
            "; sudo bundle install; sudo bundle exec berks install;")
    nil generated-buffer t))
Run Code Online (Sandbox Code Playgroud)

该bundle命令要求sudo正确安装 gems。如何使用 sudo 在 elisp 中调用此 shell 命令,输入密码,并且仍然能够在生成的窗口中显示结果?

Sea*_*ean 5

下面是一个辅助函数,它使用提供的密码以 sudo 的形式执行单个 shell 命令:

(defun sudo-shell-command (buffer password command)
  (let ((proc (start-process-shell-command
               "*sudo*"
               buffer
               (concat "sudo bash -c "
                       (shell-quote-argument command)))))
    (process-send-string proc password)
    (process-send-string proc "\r")
    (process-send-eof proc)))
Run Code Online (Sandbox Code Playgroud)

您可以将其应用到您的情况,如下所示:

(defun sudo-bundle-install (password)
  (interactive (list (read-passwd "Sudo password for bundle install: ")))
  (let ((default-directory (concat default-directory
                                   "./fixtures/test-kitchen-mode-test-run/")))
    (sudo-shell-command
     "*test-kitchen-test-setup*"
     password
     "bundle install; bundle exec berks install")
    (clear-string password)))
Run Code Online (Sandbox Code Playgroud)