‹ Hawkins.io

Bash Bootcamp: Hello World

Published: Jun 2021
Updated: Jun 2021

Every programming book starts off with the classic “Hello World” program. The program simply prints the text “Hello World”. This is simple enough to do in bash.

#!/usr/bin/env bash

echo "Hello World"

How does this work? The first line is the “shebang”. It indicates to the shell how to execute this file. I use /usr/bin/env bash because one can never never be certain where the bash executable lives on a given system (maybe /bin/bash, or even /usr/local/bin/bash). I’ve never had such a problem with /usr/bin/env bash. The following lines are executable bash commands. The echo built in command prints text to standard output. So save this file on your system as hello-world, then chmod +x hello-world, and finally run ./hello-world. Naturally your computer will say hello to you.

Great, simple enough! Now let’s parameterize this program so it can say hello to a particular person. This quick exercise illustrates how bash handles arguments. Bash programs (and functions) take any number of arguments. Bash programs also do not explicitly declare their arguments. Programs receive their arguments in numbered variables. These are also referred to as “positional arguments”. This is demonstrated below.

#!/usr/bin/env bash

echo "Hello $1"

Invoke this program by running ./hello-world bob. Naturally you’ll see a nice greeting on the screen. The $1 variable refers to the first argument given on the command line. You may ask what about $0? That’s a great question! $0 holds the name of the program itself (the first item in the command line argument list). See what’s happening? The arguments passed are available as numbered variables. Running the program with ./hello-world bob dylan assigns dylan to $2. Now that we understand argument passing, we can update the program to be strict about its arguments. After all the program can’t say hello if doesn’t know who to greet. Luckily for us bash has built in control structures. Let’s update the program to check that it’s given an argument and act accordingly.

#!/usr/bin/env bash

name="$1"

if [[ -z "${name}" ]]; then
  echo "USAGE: $0 NAME" 1>&2
  exit 1
fi

echo "Hello ${name}"

There are few things going on here. First, the name variable is assigned using =. Next we see the awkward looking bash if control structure. if evaluates to true if the given command exits 0. The [[ ]] is a built command for evaluating different conditions. In this case the -z ARG tests the given value is zero length (blank). Bash requires then keyword followed by the code to execute. The fi ends the if control structure. Inside the if block the usage instructions are printed to stderr via output redirection (1>&2). Next exit sets the exit status and terminates the process. Naturally we exit non zero because the command failed. This program is not big by any means but it mirrors structure for larger programs: declare named variables, check arguments/options, then perform the task. Patterns appear in all programming programs, this enables similar problems to be solved in the same way.