Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass an arbitrary block of commands to a bash function?

Tags:

bash

I am working on a bash script where I need to conditionally execute some things if a particular file exists. This is happening multiple times, so I abstracted the following function:

function conditional-do {
    if [ -f $1 ]
    then
        echo "Doing stuff"
        $2
    else
        echo "File doesn't exist!"
    end
}

Now, when I want to execute this, I do something like:

function exec-stuff {
    echo "do some command"
    echo "do another command"
}
conditional-do /path/to/file exec-stuff

The problem is, I am bothered that I am defining 2 things: the function of a group of commands to execute, and then invoking my first function.

I would like to pass this block of commands (often 2 or more) directly to "conditional-do" in a clean manner, but I have no idea how this is doable (or if it is even possible)... does anyone have any ideas?

Note, I need it to be a readable solution... otherwise I would rather stick with what I have.

like image 537
Mike Stone Avatar asked Sep 19 '08 21:09

Mike Stone


People also ask

How do you pass a parameter to a function in bash?

Bash Function Arguments To pass arguments to a function, add the parameters after the function call separated by spaces.

How do I pass multiple parameters in bash?

You can pass more than one argument to your bash script. In general, here is the syntax of passing multiple arguments to any bash script: script.sh arg1 arg2 arg3 … The second argument will be referenced by the $2 variable, the third argument is referenced by $3 , .. etc.

How do you pass arguments to a shell script?

Syntax for defining functions: To invoke a function, simply use the function name as a command. To pass parameters to the function, add space-separated arguments like other commands. The passed parameters can be accessed inside the function using the standard positional variables i.e. $0, $1, $2, $3, etc.


1 Answers

This should be readable to most C programmers:

function file_exists {
  if ( [ -e $1 ] ) then 
    echo "Doing stuff"
  else
    echo "File $1 doesn't exist" 
    false
  fi
}

file_exists filename && (
  echo "Do your stuff..."
)

or the one-liner

file_exists filename && echo "Do your stuff..."

Now, if you really want the code to be run from the function, this is how you can do that:

function file_exists {
  if ( [ -e $1 ] ) then 
    echo "Doing stuff"
    shift
    $*
  else
    echo "File $1 doesn't exist" 
    false
  fi
}

file_exists filename echo "Do your stuff..."

I don't like that solution though, because you will eventually end up doing escaping of the command string.

EDIT: Changed "eval $*" to $ *. Eval is not required, actually. As is common with bash scripts, it was written when I had had a couple of beers ;-)

like image 143
Ludvig A. Norin Avatar answered Sep 21 '22 02:09

Ludvig A. Norin