[Bash] Returning from functions performatically


So, once a while I posted some shell script tips. Now, let's see a little more, this time about functions and returning values.

First, the basics

Creating a function in bash is as simple like this:

#!/bin/bash
fnc_name() {
  echo "Inside the function"
}

# Calling the function
fnc_name

The semantic for declaring a function is defined as:

function name() { code ... }

One important note here. The function can be declared without the "function" keyword, but the parenteses must be present, otherwise the same, you can ommit the parenteses, but the "function" keyword must be present:

#!/bin/bash

# This is corret
function fnc_name {
  echo "Declaring with function keyword"
}

# This is corret too
fnc_name_1() {
  echo "Declaring with parenteses"
}

# Combining
function fnc_name_2() {
  echo "Works too"
}

# This not works
fnc_name_3{
  echo "NOT WORKS"
}

Second, passing parameters

Every programming language has a way to pass values (so called parameters) to functions, besides bash not being a programming language it has his ways too.

#!/bin/bash

# Concatenate the parameters
# $1 - first value
# $2 - Second value
concat() {
  echo "$1 $2"
}

concat "hello" "World"

The above script prints "Hello World"

Now, the real question: How to set values from inside the function?

There are some ways to do this. Lets see:

#1: Using echo

#!/bin/bash

concat() {
  echo "$1 $2"
}

VALUE=`concat "Hello" "World"`
# Or:
# VALUE=$(concat "Hello" "World")

#2: Using eval

#!/bin/bash

# $1 - First parameter is the variable used for return
concat() {
  local _RET=$1
  eval $_RET="$2$3"
}

concat VALUE "Hello" "World"

Both ways the VALUE variable will receive the "Hello World" string. So, which one is better? There are significant difference between them? Let's produce a simple check:

#!/bin/bash

concat_v1() {
  echo "$1 $2"
}

concat_v2() {
  local _RET=$1
  eval $_RET="$2$3"
}

test_v1() {
  for i in {1..1000000}; do
    concat A B
  done
}

test_v2() {
  for i in {1..1000000}; do
    concat2 VALUE A B
  done
}

echo "Test V1"
time test_v1 > /dev/null

echo "Test V2"
time test_v2 > /dev/null

The results:

Test V1

real 0m7,316s
user 0m6,925s
sys 0m0,392s


Test V2

real 0m14,441s
user 0m14,289s
sys 0m0,152s

 

So, the simplest way is the better way.

And you? How do you do? Put in the comments and let's test. =)

See You,

How do you rate this article?

3



Everything One Technology
Everything One Technology

Here in Everything One technology you will find information about Clouds, kubernetes, database (mostly postgres) and more. Save us and keep reading. Thank You, and see you in the next page.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.