Implementing dry-run in bash scripts

How would one implement a dry-run option in a bash script?

I can think of either wrapping every single command in an if and echoing out the command instead of running it if the script is running with dry-run.

Another way would be to define a function and then passing each command call through that function.

Something like:

function _run () {
    if [[ "$DRY_RUN" ]]; then
        echo $@
    else
        $@
    fi
}

`_run mv /tmp/file /tmp/file2`

`DRY_RUN=true _run mv /tmp/file /tmp/file2`

Is this just wrong and there is a much better way of doing it?


See BashFAQ/050: I'm trying to put a command in a variable, but the complex cases always fail! for a discussion of this subject.

Although now removed, the section How to add testing capability to a programs may still be useful.


I wanted to play with the answer from @Dennis Williamson's. Here's what I got:

Run () {
    if [ "$TEST" ]; then
        echo "$*"
        return 0
    fi

    eval "$@"
}

The eval "$@" is important here, and is better then simply doing $*. $@ returns all parameters and $* returns all parameters with no whitespace/quoting.

$ mkdir dir
$ touch dir/file1 dir/file2
$ FOO="dir/*"
$ TEST=true Run ls -l $FOO
ls -l dir/file1 dir/file2
$ Run ls -l $FOO
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file1
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file2