Function: eshell-command
eshell-command is an autoloaded, interactive and byte-compiled
function defined in eshell.el.gz.
Signature
(eshell-command COMMAND &optional OUTPUT-TARGET ERROR-TARGET)
Documentation
Execute the Eshell command string COMMAND.
If OUTPUT-TARGET is t (interactively, with the prefix argument), write
the command's standard output to the current buffer at point. If nil,
write the output to a new output buffer. For any other value, output to
that Eshell target (see eshell-get-target).
ERROR-TARGET is similar to OUTPUT-TARGET, except that it controls where to write standard error, and a nil value means to write standard error to the same place as standard output. (To suppress standard error, you can write to the Eshell virtual target "/dev/null".)
When "&" is added at end of command, the command is async and its
output appears in a specific buffer. You can customize
eshell-command-async-buffer to specify what to do when this output
buffer is already taken by another running shell command.
Probably introduced at or before Emacs version 31.1.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/eshell/eshell.el.gz
;;;###autoload
(defun eshell-command (command &optional output-target error-target)
"Execute the Eshell command string COMMAND.
If OUTPUT-TARGET is t (interactively, with the prefix argument), write
the command's standard output to the current buffer at point. If nil,
write the output to a new output buffer. For any other value, output to
that Eshell target (see `eshell-get-target').
ERROR-TARGET is similar to OUTPUT-TARGET, except that it controls where
to write standard error, and a nil value means to write standard error
to the same place as standard output. (To suppress standard error, you
can write to the Eshell virtual target \"/dev/null\".)
When \"&\" is added at end of command, the command is async and its
output appears in a specific buffer. You can customize
`eshell-command-async-buffer' to specify what to do when this output
buffer is already taken by another running shell command."
(interactive (list (eshell-read-command)
(not (not current-prefix-arg))))
(save-excursion
(let ((stdout (cond ((eq output-target t) (current-buffer))
((not output-target) t)
(t output-target)))
(stderr (if (eq error-target t) (current-buffer) error-target))
(buf (set-buffer (generate-new-buffer " *eshell cmd*")))
(eshell-non-interactive-p t))
(eshell-mode)
(let* ((proc (eshell-eval-command
`(eshell-with-handles (',stdout 'insert ',stderr 'insert)
(let ((eshell-current-subjob-p))
,(eshell-parse-command command)))
command))
(async (eq (car-safe proc) :eshell-background))
(bufname (cond
((not (eq stdout t)) nil)
(async eshell-command-buffer-name-async)
(t eshell-command-buffer-name-sync)))
unique)
(when bufname
(when (buffer-live-p (get-buffer bufname))
(cond
((with-current-buffer bufname
(and (null eshell-foreground-command)
(null eshell-background-commands)))
;; The old buffer is done executing; kill it so we can
;; take its place.
(kill-buffer bufname))
((eq eshell-command-async-buffer 'confirm-kill-process)
(shell-command--same-buffer-confirm "Kill it")
(with-current-buffer bufname
;; Stop all the processes in the old buffer (there may
;; be several).
(eshell-round-robin-kill))
(kill-buffer bufname))
((eq eshell-command-async-buffer 'confirm-new-buffer)
(shell-command--same-buffer-confirm "Use a new buffer")
(setq unique t))
((eq eshell-command-async-buffer 'new-buffer)
(setq unique t))
((eq eshell-command-async-buffer 'confirm-rename-buffer)
(shell-command--same-buffer-confirm "Rename it")
(with-current-buffer bufname
(rename-uniquely)))
((eq eshell-command-async-buffer 'rename-buffer)
(with-current-buffer bufname
(rename-uniquely)))))
(rename-buffer bufname unique))
;; things get a little coarse here, since the desire is to
;; make the output as attractive as possible, with no
;; extraneous newlines
(unless async
(funcall #'eshell-wait-for-processes (cadr eshell-foreground-command))
(cl-assert (not eshell-foreground-command))
(goto-char (point-max))
(while (and (bolp) (not (bobp)))
(delete-char -1)))
(cl-assert (and buf (buffer-live-p buf)))
(unless bufname
(let ((len (if async 2
(count-lines (point-min) (point-max)))))
(cond
((= len 0)
(message "(There was no command output)")
(kill-buffer buf))
((= len 1)
(message "%s" (buffer-string))
(kill-buffer buf))
(t
(save-selected-window
(select-window (display-buffer buf))
(goto-char (point-min))
;; cause the output buffer to take up as little screen
;; real-estate as possible, if temp buffer resizing is
;; enabled
(and (not async) temp-buffer-resize-mode
(resize-temp-buffer-window)))))))))))