I am looking for a way to display and interact with long running shell scripts in a separate buffer. While using eshell works, I'd like to automate most shell tasks using elisp.

The best way I came up with is (example for git pull):

(let ((new-buffer (get-buffer-create "*script*")))
     (switch-to-buffer-other-window new-buffer)
     (eshell-command "git pull" t)))

While this displays procedural output in a new buffer, emacs locks until the process finishes and I can't interact with git if it prompts for information.

(start-process "script" new-buffer "git" "pull") runs asynchronously, but does not accept interactive input either.

The git pull command is just an example here.


I think I got everything I wanted using make-comint-in-buffer. I got correct ansi-colors and can interact with the process if it reads stdin.

Just the gist:

(let* ((script-proc-buffer 
           (apply 'make-comint-in-buffer "script" new-buffer "git" nil '("pull")))
       (script-proc (get-buffer-process script-proc-buffer)))

    (set-process-sentinel script-proc 'special-mode-sentinel))

Where special-mode-sentinel is a defun that switches to special-mode when the process has finished, allowing me to quit the buffer using q.

It's not pretty, but it works...

  • 1
    Did you already take a look at (elisp) Asynchronous Processes?
    – Drew
    Feb 7, 2018 at 22:31
  • Yes, that's where I found start-process and start-process-shell-command. start-process-shell-command almost does what I want, but I can't figure out how to interact with the process if it prompts for input (e.g. a password). But I'm quite new to elisp, so maybe I am missing something...
    – mconrads
    Feb 7, 2018 at 22:51
  • The (elisp) Filter Functions part is where you want to look at. PS catching git password prompts requires a pty, so it won't work under Windows.
    – npostavs
    Feb 8, 2018 at 0:15
  • @npostavs Reading up on the filter functions led me to comint-mode (which may be overkill). Thanks for the link!
    – mconrads
    Feb 12, 2018 at 22:47

1 Answer 1


Simply use the following function

(async-shell-command "git pull" "*script*")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.