Emacs将进程称为sudo

Emacs将进程称为sudo,emacs,elisp,sudo,Emacs,Elisp,Sudo,更新 我接受了@Sean的回答,只是做了一些小的修改 (defun sudo-shell-command (buffer password command) (let ((proc (start-process-shell-command "*sudo*" buffer (concat "sudo bash -c " (shell-quote-argument command)))))

更新

我接受了@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)))

假设我需要在elisp中调用一个进程,该进程需要sudo权限。例如,运行Ruby的
捆绑安装

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

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

您需要使用密码创建一个文件:

(defun my-run-command-under-sudo (password command &rest cpsc-args)
  "Run COMMAND under sudo with your PASSWORD.
Other arguments are passed to `call-process-shell-command'
 and should start with BUFFER (the output destination).
NB: this is _not_ secure: it creates a temp file with your password."
  (let ((password-file (make-temp-file "elisp-sudo")))
    (with-temp-file password-file (insert password))
    (unwind-protect
         (apply 'call-process-shell-command
                (concat "sudo " command)
                password-file cpsc-args)
      (delete-file password-file))))
(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)))
现在您可以执行以下操作:

(let ((default-directory (concat default-directory "./fixtures/test-kitchen-mode-test-run")))
  (my-run-command-under-sudo "my-password" "bundle install" t)
  (my-run-command-under-sudo "my-password" "bundle exec berks install" t))

您需要使用密码创建一个文件:

(defun my-run-command-under-sudo (password command &rest cpsc-args)
  "Run COMMAND under sudo with your PASSWORD.
Other arguments are passed to `call-process-shell-command'
 and should start with BUFFER (the output destination).
NB: this is _not_ secure: it creates a temp file with your password."
  (let ((password-file (make-temp-file "elisp-sudo")))
    (with-temp-file password-file (insert password))
    (unwind-protect
         (apply 'call-process-shell-command
                (concat "sudo " command)
                password-file cpsc-args)
      (delete-file password-file))))
(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)))
现在您可以执行以下操作:

(let ((default-directory (concat default-directory "./fixtures/test-kitchen-mode-test-run")))
  (my-run-command-under-sudo "my-password" "bundle install" t)
  (my-run-command-under-sudo "my-password" "bundle exec berks install" t))

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

(defun my-run-command-under-sudo (password command &rest cpsc-args)
  "Run COMMAND under sudo with your PASSWORD.
Other arguments are passed to `call-process-shell-command'
 and should start with BUFFER (the output destination).
NB: this is _not_ secure: it creates a temp file with your password."
  (let ((password-file (make-temp-file "elisp-sudo")))
    (with-temp-file password-file (insert password))
    (unwind-protect
         (apply 'call-process-shell-command
                (concat "sudo " command)
                password-file cpsc-args)
      (delete-file password-file))))
(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)))
您可以将其应用于您的情况,如下所示:

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

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

(defun my-run-command-under-sudo (password command &rest cpsc-args)
  "Run COMMAND under sudo with your PASSWORD.
Other arguments are passed to `call-process-shell-command'
 and should start with BUFFER (the output destination).
NB: this is _not_ secure: it creates a temp file with your password."
  (let ((password-file (make-temp-file "elisp-sudo")))
    (with-temp-file password-file (insert password))
    (unwind-protect
         (apply 'call-process-shell-command
                (concat "sudo " command)
                password-file cpsc-args)
      (delete-file password-file))))
(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)))
您可以将其应用于您的情况,如下所示:

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

sudo捆绑包安装
@lunaryorn对于工作中的厨师开发,所有工作站都使用系统ruby。我个人在我的家用机器上使用rvm,但工作站不是由
my\u example\u usr:staff
拥有的/usr/local设置的,因此这意味着使用
sudo
。选择你的战斗,我猜。@lunaryorn另外,这个sudo调用只在默认情况下以我在ert测试设置中编写的模式执行。我将提供一个使用sudo执行bundle exec的选项,但在实际模式下默认情况下它将关闭。
sudo bundle install
@lunaryorn对于工作中的厨师开发,所有工作站都使用系统ruby。我个人在我的家用机器上使用rvm,但工作站不是由
my\u example\u usr:staff
拥有的/usr/local设置的,因此这意味着使用
sudo
。选择你的战斗,我猜。@lunaryorn另外,这个sudo调用只在默认情况下以我在ert测试设置中编写的模式执行。我将提供一个使用sudo执行bundle exec的选项,但在实际模式下它将默认关闭。我认为process send string正是我想要的!早上我会把它插上,然后告诉你我发现了什么。我假设密码会以明文形式出现在日志中的某个地方,对吗?我不这么认为,不。我想说的是,我会小心确保sudo确实总是要求密码。这段代码只向先读取其标准输入的进程提供密码。这可以工作,但不会显示生成的缓冲区。我已更新了上面的问题,以包括正确显示生成的缓冲区所需的代码更改。请更新您的答案并ping我,这样我就可以删除上面问题中的更新部分,您就可以获得帮助我解决此问题所应得的全部荣誉。:-)我想进程发送字符串正是我要找的!早上我会把它插上,然后告诉你我发现了什么。我假设密码会以明文形式出现在日志中的某个地方,对吗?我不这么认为,不。我想说的是,我会小心确保sudo确实总是要求密码。这段代码只向先读取其标准输入的进程提供密码。这可以工作,但不会显示生成的缓冲区。我已更新了上面的问题,以包括正确显示生成的缓冲区所需的代码更改。请更新您的答案并ping我,这样我就可以删除上面问题中的更新部分,您就可以获得帮助我解决此问题所应得的全部荣誉。:-)