38.8 Shell Commands in Dired
The Dired command ! (dired-do-shell-command
) reads a shell
command string in the minibuffer and runs that shell command on all the
specified files. X is a synonym for !. You can specify the
files to operate on in the usual ways for Dired commands
(see Operating on Files). There are two ways of applying a shell
command to multiple files:
- If you use ‘*’ surrounded by whitespace in the shell command,
then the command runs just once, with the list of file names
substituted for the ‘*’. The order of file names is the order of
appearance in the Dired buffer.
Thus, ! tar cf foo.tar * <RET> runs tar
on the entire
list of file names, putting them into one tar file foo.tar.
If you want to use ‘*’ as a shell wildcard with whitespace around
it, write ‘*""’. In the shell, this is equivalent to ‘*’;
but since the ‘*’ is not surrounded by whitespace, Dired does
not treat it specially.
- If the command string doesn't contain ‘*’ surrounded by
whitespace, then it runs once for each file. Normally the file
name is added at the end.
For example, ! uudecode <RET> runs uudecode
on each
file.
- However, if the command string contains ‘?’ surrounded by
whitespace, the current file name is substituted for ‘?’ (rather
than added at the end). You can use ‘?’ this way more than once
in the command, and the same file name replaces each occurrence.
To iterate over the file names in a more complicated fashion, use an
explicit shell loop. For example, here is how to uuencode each file,
making the output file name by appending ‘.uu’ to the input file
name:
for file in * ; do uuencode "$file" "$file" >"$file".uu; done
The working directory for the shell command is the top-level directory
of the Dired buffer.
The ! command does not attempt to update the Dired buffer to show
new or modified files, because it doesn't really understand shell
commands, and does not know what files the shell command changed. Use
the g command to update the Dired buffer (see Dired Updating).