EINVAL: Valid solutions for invalid problems

Running shell commands from Emacs Dired

dired-do-shell-command (bound to ! in dired) can handle multiple marked files in a few different ways. They are quite intuitive but I always wished for a cheatsheet with all the options, so here I am, creating one.

implicit file single file multiple files
foreground cat cat foo ? bar cat foo * bar
background parallel cat & cat foo ? bar & cat foo * bar &
background sequential cat ; cat foo ? bar ; cat foo * bar ;

Read further for a little more detailed explanation of each option.


Implicit file argument

Foreground

cat

for file in "${marks[@]}"; do
    cat "$file"
done

Background parallel

cat &

for file in "${marks[@]}"; do
    cat "$file" &
done

Background sequential

cat ;
cat ;&

for file in "${marks[@]}"; do
    cat "$file"
done &

Single file per command

Foreground

cat foo ? bar

for file in "${marks[@]}"; do
    cat foo "$file" bar
done

Use `?` to use a filename as a part of a longer argument:

cat foo`?`bar

for file in "${marks[@]}"; do
    cat "foo${file}bar"
done

Background parallel

cat foo ? bar &

for file in "${marks[@]}"; do
    cat foo "$file" bar &
done

Background sequential

cat foo ? bar ;
cat foo ? bar ;&

for file in "${marks[@]}"; do
    cat foo "$file" bar
done &

All files in a single command

Foreground

cat foo * bar

cat foo "${marks[@]}" bar

Use *"" to pass an explicit * to the shell (globbing):

cat foo * bar *""

cat foo "${marks[@]}" bar *

Background parallel

cat foo * bar &

cat foo "${marks[@]}" bar &

Background sequential

cat foo * bar ;
cat foo * bar ;&

The same behavior as the parallel call when * is in use.