Here's something you didn't know about bash functions. Usually when you write a function you do this:

function name () {
  ...
}

Right? I know you do, because that's how everyone writes functions. Well, here's the thing. In bash { ... } doesn't mean "function's body" or "function's scope" as in JavaScript or C. It's actually a compound command. You can do all kinds of fancy things like this:

function fileExists () [[ -f $1 ]]

No need for those curly braces! Function is the test command itself. Or you can do this:

function isEven () (( $1 % 2 == 0 ))

Here function is an arithmetic expression. Or you can do this:

function name () (
  ...
)

This will spawn the function in a subshell rather than execute it in the current environment.

Or you can use while, if, case, select and for. Here's an example:

function sleep1 () while :; do "$@"; sleep 1; done

This one creates a function sleep1 that runs a command every one second forever. You can do things like sleep1 df -h to monitor how your disk changes.

Not only do these tricks make your code nicer and let you write quick bash one liners, but they also are super useful. It's especially useful if you need to create a temporary environment for your function and temporarily change variables or shell options. Here's an example I found somewhere in my code:

function caseInsensitiveMatch () (
    shopt -s nocasematch
    ....
)

Here funtion caseInsensitiveMatch executes in a subshell and sets nocasematch option and its scope is just this function. Similarly for IFS and other variables you often need a temporarily change. No need to save previous values, then restore them.

This was my quick 5 minute shell tip. Look up compound commands in bash man page to find all the possibilities. Once you master this, you'll start writing some next level shell code. Until next time!

This article is part of my upcoming book Bash One Liners (freely available on my blog.)

Comments

Leandro Permalink
April 01, 2017, 14:35

So, the question is, can you create a multiline function without the (...) or {...}, like in python syntax? For an example of python syntax, see: https://www.tutorialspoint.com/python/python_functions.htm

April 02, 2017, 11:54

No, because function's body has to be a compound statement.

Henri Salo Permalink
April 02, 2017, 07:44

"You can do things like sleep1 df -h to monitor how your memory changes."

Disk changes?

April 02, 2017, 11:54

Now updated.

April 02, 2017, 12:13

This is a great observation, thanks! I'll be refactoring my bash functions to use this, though it will mean longer conversations with colleagues who believe bash is voodoo. :)

June 25, 2017, 03:52

The `function` keyword is better skipped for increased portability. See the !function factoid on freenode/greybot

name () { ...; }

Leave a new comment

(why do I need your e-mail?)

(Your twitter handle, if you have one.)

Type the word "halflife3_569": (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.

Advertisements