הלינקייה: מגזין חודשי למפתחים

רוצה לשמוע על כל האירועים, המדריכים, הקורסים והמאמרים שנכתבו החודש ?
הלינקייה הינו מגזין חופשי בעברית שמשאיר אותך בעניינים.
בלי ספאם. בלי שטויות. פעם בחודש אצלך בתיבה.

Bash Functions

Functions provide the basic building block of code reuse. In bash, we can take frequently used
lines of code and wrap them in a block called function. Afterwards, we can
call these blocks from anywhere in the program, passing arguments to influence
their behavior.

A bash function is defined with the special keyword function, or, like a normal variable
with the parenthesis suffix. I recommend to use the function keyword for it is more
readable.

In this chapter, I will show how to define a function, and how to call it with arguments.

Declaring A Simple Function

Taking a frequently used code block and wrapping it for reuse is very easy. Just find a
name for it, and prefix that name with the word "function".

# The hello function will greet its users with the traditional
# Hello World greeting

function hello {
  echo Hello World
}

# We call that function simply by specifying its name as a command.
# so now this line prints Hello World
hello

Working With Arguments

When declaring bash functions, the positional parameters take the value of the function's
arguments, starting with 1, and the $# is updated automatically to the number of arguments passed.
Here's a more generic Hello World function that also takes a user name.


function hello {
  echo Hello $1
}

function greet {
  echo Hello $*
}

# Print Hello Fearless
hello Fearless Leader

# Print Hello Fearless Leader
greet Fearless Leader

Local Function Variables

A function can work with variables to be more productive or store middle calculations.
Those variables are usually not required in the outside world, so to avoid collisions, we
use the local keyword. When a variable is declared local, it will not be accessible from
outside the function scope.

A function can also return a value. If it does, that value is stored in the $? variable.


function sum {
  local sum=0
  for n in $*; do
    let sum+=$n
  done

  return $sum
}

sum 1 2 3 4
# prints: Sum is 10
echo "Sum is $?"

Put It All Together

This final example prints the directory layout recursively in tree-like structure.

function tree {
# $1 is the first argument passed to the function
# Here we take it as the current indentation level
  if [[ $1 ]]; then
    local indent=$1
  else
    local indent=""
  fi

  for fname in *; do
    if [[ -f $fname ]]; then
      echo "$indent""$fname"
    elif [[ -d "$fname" ]]; then
      echo "$indent""$fname"
# A recursive call to tree lets us run easily over internal
# sub-directories. We use a subshell so when the call ends we'll
# get back to the same working directory.
      (cd "$fname"; tree "$indent  ")
    fi
  done
}

if [[ $1 ]]; then
  dirname=$1
else
  dirname="."
fi

(cd $dirname; tree)