Interpreter directive

We can use #! ( a shebang) to define which interpreter should run the file. It is followed by the path to an interpreter:

#!/bin/bash

Parameter expansion

${var} is the Bash variable expansion syntax. To set it, simply do var="/var/log". It can then be used with expansion.

In Fish, the syntax is set /var/log.

Test operators

These operators return booleans.

OperatorUse
-dand whether file is a dir or not
-fwhether something exists on the file system
-nis string not empty
-zis string empty

Example

name=""
if [ -z "$name" ]; then
  echo "Empty"
fi
 
name="Alice"
if [-n "$name"]; then
  echo "Not empty"
fi

Command substitution

Inserts the result of a command directly into another command. When writing 'foo' (with single quotation marks) the shell reads it as a string literal; if written as $(foo) the shell will run a subshell and then replace the value of foo with the output of the command that was run. If we want to embed the command substitution in a string, use double quotes ".

Example

root@DietPi:~# echo 'I am $(hostname)'

I am (hostname) root@DietPi:~# echo "I am (hostname)” I am DietPi

Sub shell execution

To execute a command in a new, separate process, use (command). We can chain them (command1; command2).

Example

This command will print the current directory, switches directory, lists the files, prints the current dir again, and then we are back wherever we ran the original command.

root@DietPi:~# (pwd; cd /etc; ls; pwd)

Note that Fish doesn’t support subshell execution.

Functions

Functions in bash are written with the shape:

my_func() {
	# do stuff
}

Note

Bash functions can only return numeric exit codes; to pass text data around we must use echo.

Important

In Bash shell scripts, variables by default are global. To declare scope a variable to the local function, use the local keyword:

function_name() {local var=value; }

Field separators

Shell scripts have two types of separators, IFS(internal field separator) and OFS (output field separator). They control how text will be split.

In Bash there is a tendency to treat spaces, tabs, and newlines inside a variable as natural break-points.

If we are trying to read something like a CSV file, we can re-define the IFS to use commas and then redirect the CSV into read or the like:

IFS=',' read -r name age city <<< "alice,24,Denver"
echo "$name is $age lives in $city"

OFS, on the other hand, is commonly used with awk.

Conditionals

if statements can be written with the shape:

if [ "$condition" ]; then
	"$command"
else
	"$other_command"
fi

There are also case conditionals available:

case "$action" in
	start)
		"$start_command"
		;;
	stop)
		"$stop_command"
		;;
	*)
		"$default_command"
		;;
esac

Loops

There are three loops: for, while, and until.

for loops are defined like this:

for name in Alice Bob Charlies
	do
		echo "Hello, $name!"
	done

A while loop is defined as:

counter=1
while [ $counter -le 3 ]
	do
		((counter++))
	done

until loops are like while loops, except that they run until a true condition:

counter=1
until [ $counter -gt 3 ]
	do
		((counter++))
	done

Numerical comparisons

Do compare numbers we use special flags: -eq (equal to), -ne (not equal to), -gt/-lt (greater than/less than) etc. These are always used inside square brackets when making a comparison

while [ $counter -le 3 ]

String comparisons

Common string comparison operators are:

OperatorDescription
== and =Equality
!=inequality
=~Regex
<= and >=Alphabetical comparison

The difference between == and = is that the former is used inside double square brackets, while the latter is used inside single square brackets.

Linux Shell Redirection