You could use a wrapper command that:
- renames the file
- runs the viewer in background
- cleans up when the viewer has returned instead of letting
mutt do it.
Something like:
#! /bin/sh -
TMPDIR=$(
mutt -D 2> /dev/null |
awk -F\" '
$1 == "tmpdir=" {
gsub("~", ENVIRON["HOME"], $2)
print $2
exit
}'
)
[ -n "$TMPDIR" ] || exit
export TMPDIR
nargs=$#
nfiles=0
for i do
case $i in
("$TMPDIR"/?*)
new_file=$(mktemp -ut "XXXXX${i##*/}") &&
mv -- "$i" "$new_file" &&
nfiles=$(($nfiles + 1)) &&
set -- "$new_file" "$@" "$new_file" &&
continue
esac
set -- "$@" "$i"
done
run_command() (
shift "$(($nargs + $nfiles))"
exec "$@"
)
(
run_command "$@"
while [ "$nfiles" -gt 0 ]; do
set -- "$@" "$1"
shift
nfiles=$(($nfiles - 1))
done
shift "$((2*$nargs))"
rm -f -- "$@"
) &
And put something like:
image/*; muttv eog %s;
Where muttv is that script above.
The above makes no assumption on where the filename(s) appear(s) in the list of arguments or what character they contains... Which is why we first ask mutt what its tmpdir is (so we use that to determine what are the files to view).
In most cases, it would be overkill though, and as Gilles points out may not work if tmpdir is specified as relative to your mailbox folder.
A simpler one would be:
#! /bin/sh -
nargs=$#
eval "file=\${$nargs}"
newfile=$(dirname -- "$file")/new-$(basename -- "$file")
while [ "$nargs" -gt 1 ]; do
set -- "$@" "$1"
shift
nargs=$(($nargs - 1))
done
shift
mv -- "$file" "$newfile" || exit
(
"$@" "$newfile"
rm -f -- "$newfile"
) &
Replace mv with cp if you don't want to touch the original file provided by mutt.