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 $@

`_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?

  • So, you want to print what the command will do (including the values of the $VARIABLES) without actually executing the command. I use something like your _run() function, sometimes with 'set -xv', but I would love a better way. Commented Jun 2, 2010 at 22:46
  • yeah, exactly that. I'm wondering if there isn't an internal variable you can set in bash so commands don't actually execute, instead of passing them through a function Commented Jun 2, 2010 at 22:48
  • 2
    There's no reason that this question should have been marked community wiki. Commented Jun 2, 2010 at 23:36
  • Bash is a shell. There is no reason for it to do dry runs. I don't think there is a better way of doing it than you've already done.
    – d-_-b
    Commented Jun 3, 2010 at 0:31

2 Answers 2


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.

  • Not an alternative, but it looks like an excellent resource for testing and working with longer bash programs. Commented Jun 3, 2010 at 8:03
  • 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. Commented Jun 3, 2010 at 9:34
  • It would be far more useful if this answer summarised the salient points of this article. One line answers are still poor answers.
    – Mark Booth
    Commented Nov 3, 2015 at 10:53

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

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

    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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .