Function: dired-do-shell-command

dired-do-shell-command is an autoloaded, interactive and byte-compiled function defined in dired-aux.el.gz.

Signature

(dired-do-shell-command COMMAND &optional ARG FILE-LIST)

Documentation

Run a shell command COMMAND on the marked files.

If no files are marked or a numeric prefix arg is given, the next ARG files are used. Just C-u (universal-argument) means the current file. The prompt mentions the file(s) or the marker, as appropriate.

If there is a * in COMMAND, surrounded by whitespace, this runs COMMAND just once with the entire file list substituted there.

If there is no *, but there is a ? in COMMAND, surrounded by whitespace, or a ``?`' this runs COMMAND on each file individually with the file name substituted for ? or ``?`'.

Otherwise, this runs COMMAND on each file individually with the file name added at the end of COMMAND (separated by a space).

* and ? when not surrounded by whitespace nor ``' have no special
significance for dired-do-shell-command, and are passed through normally to the shell, but you must confirm first.

If you want to use * as a shell wildcard with whitespace around it, write *"" in place of just *. This is equivalent to just
* in the shell, but avoids Dired's special handling.

If COMMAND ends in &, ;, or ;&, it is executed in the background asynchronously, and the output appears in the buffer named by shell-command-buffer-name-async. When operating on multiple files and COMMAND ends in &, the shell command is executed on each file in parallel. However, when COMMAND ends in ; or ;&, then commands are executed in the background on each file sequentially waiting for each command to terminate before running the next command. You can also use dired-do-async-shell-command that automatically adds &.

Otherwise, COMMAND is executed synchronously, and the output appears in the buffer named by shell-command-buffer-name.

This feature does not try to redisplay Dired buffers afterward, as there's no telling what files COMMAND may have changed. Type M-x dired-do-redisplay (dired-do-redisplay) to redisplay the marked files.

When COMMAND runs, its working directory is the top-level directory of the Dired buffer, so output files usually are created there instead of in a subdir.

In a noninteractive call (from Lisp code), you must specify the list of file names explicitly with the FILE-LIST argument, which can be produced by dired-get-marked-files, for example.

dired-guess-shell-alist-default and dired-guess-shell-alist-user are consulted when the user is prompted for the shell command to use interactively.

Also see the dired-confirm-shell-command variable.

View in manual

Probably introduced at or before Emacs version 21.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/dired-aux.el.gz
;;;###autoload
(defun dired-do-shell-command (command &optional arg file-list)
  "Run a shell command COMMAND on the marked files.
If no files are marked or a numeric prefix arg is given,
the next ARG files are used.  Just \\[universal-argument] means the current file.
The prompt mentions the file(s) or the marker, as appropriate.

If there is a `*' in COMMAND, surrounded by whitespace, this runs
COMMAND just once with the entire file list substituted there.

If there is no `*', but there is a `?' in COMMAND, surrounded by
whitespace, or a `\\=`?\\=`' this runs COMMAND on each file
individually with the file name substituted for `?' or `\\=`?\\=`'.

Otherwise, this runs COMMAND on each file individually with the
file name added at the end of COMMAND (separated by a space).

`*' and `?' when not surrounded by whitespace nor `\\=`' have no special
significance for `dired-do-shell-command', and are passed through
normally to the shell, but you must confirm first.

If you want to use `*' as a shell wildcard with whitespace around
it, write `*\"\"' in place of just `*'.  This is equivalent to just
`*' in the shell, but avoids Dired's special handling.

If COMMAND ends in `&', `;', or `;&', it is executed in the
background asynchronously, and the output appears in the buffer named
by `shell-command-buffer-name-async'.  When operating on multiple files
and COMMAND ends in `&', the shell command is executed on each file
in parallel.  However, when COMMAND ends in `;' or `;&', then commands
are executed in the background on each file sequentially waiting for
each command to terminate before running the next command.  You can
also use `dired-do-async-shell-command' that automatically adds `&'.

Otherwise, COMMAND is executed synchronously, and the output
appears in the buffer named by `shell-command-buffer-name'.

This feature does not try to redisplay Dired buffers afterward, as
there's no telling what files COMMAND may have changed.
Type \\[dired-do-redisplay] to redisplay the marked files.

When COMMAND runs, its working directory is the top-level directory
of the Dired buffer, so output files usually are created there
instead of in a subdir.

In a noninteractive call (from Lisp code), you must specify
the list of file names explicitly with the FILE-LIST argument, which
can be produced by `dired-get-marked-files', for example.

`dired-guess-shell-alist-default' and
`dired-guess-shell-alist-user' are consulted when the user is
prompted for the shell command to use interactively.

Also see the `dired-confirm-shell-command' variable."
  ;; Functions dired-run-shell-command and dired-shell-stuff-it do the
  ;; actual work and can be redefined for customization.
  (interactive
   (let ((files (dired-get-marked-files t current-prefix-arg nil nil t)))
     (list
      ;; Want to give feedback whether this file or marked files are used:
      (dired-read-shell-command "! on %s: " current-prefix-arg files)
      current-prefix-arg
      files)))
  (let* ((on-each (not (dired--star-or-qmark-p command "*" 'keep)))
	 (no-subst (not (dired--star-or-qmark-p command "?" 'keep)))
         (confirmations nil)
         ;; Get confirmation for wildcards that may have been meant
         ;; to control substitution of a file name or the file name list.
         (ok (cond
              ((not (or on-each no-subst))
               (error "You can not combine `*' and `?' substitution marks"))
              ((not dired-confirm-shell-command)
               t)
              ((setq confirmations (dired--need-confirm-positions command "*"))
               (dired--no-subst-confirm confirmations command))
              ((setq confirmations (dired--need-confirm-positions command "?"))
               (dired--no-subst-confirm confirmations command))
              (t))))
    (cond ((not ok) (message "Command canceled"))
          (t
           (if on-each
	       (dired-bunch-files (- 10000 (length command))
                                  (lambda (&rest files)
                                    (dired-run-shell-command
                                     (dired-shell-stuff-it command files t arg)))
                                  nil file-list)
	     ;; execute the shell command
	     (dired-run-shell-command
              (dired-shell-stuff-it command file-list nil arg)))))))