Monday, January 24, 2011

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 for a discussion of this subject.

    Apikot : Not an alternative, but it looks like an excellent resource for testing and working with longer bash programs.
    Dennis Williamson : I rolled back the edit that added an anchor to a particular part of the linked page since the point of my answer, as stated, is to read the discussion as a whole rather than point to one specific how-to portion. The point of the linked page is generally to try to avoid putting commands to be executed into variables since there are a lot of gotchas.
  • 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 $* like you did above. I forget why this is exactly (too tired), but I'll try to explain it when I'm less tired (Sorry!)

    $ 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
    

0 comments:

Post a Comment