Skip to content

Bash basics

About

Bash (Bourne Again SHell) is a widely used shell and command language in Unix-like operating systems. It is the default shell for most Linux distributions and macOS.

The language

Shell prompt

Opening a terminal shows the prompt. It typically ends

  • with a dollar sign ($) for regular users
  • with a hash (#) for the root user.

Text editors for creating and modifying files

To open text files, integrated editors can be used, such as nano or vim:

nano filename
vim filename

Asking for help

man command
command --help

Running Scripts

Each .sh script have to begin with a shebang.

#!/bin/bash

And can be executed as follows:

./myscript.sh
# or
sh myscript.sh

How bash works

Each time bash is executed, it runs one of the following scripts

  • /etc/profile
  • /etc/bash.bashrc provided its existence.

Then it searches:

  • ~/.bash_login
  • ~/.bash_profile
  • ~/.profile (only in non interactive shells without login)

When bash is exited, it runs ~/.bash_logout

Good practices

Enclose variables into quotes

This practice will prevent from raising errors where the variable might be empty or contains spaces. Just use if [ -z "$VENV_NAME" ] || [ -z "$VENV_PATH" ]; then instead of if [ -z $VENV_NAME ] || [ -z $VENV_PATH ]; then.

Environment variables

Home directory for the current user

echo $HOME

Current username

echo $USER
# or
echo $LOGNAME

Present Working Directory (PWD)

echo $PWD

PATH

List of directories where the shell looks for executables as a colon-separated list of directories.

echo $PATH

Path of the current shell

echo $SHELL

Terminal type

echo $TERM

Primary prompt string

Is the text displayed before each command.

echo $PS1

Hostname of the computer

echo $HOSTNAME

Operating System Type

echo $OSTYPE

Language and local settings

echo $LANG
echo $LC_COLLATE
# ... and others

User ID and effective user ID for the current user

echo $UID
echo $EUID

Version number of bash

echo $BASH_VERSION

Random number

Gets a random number between 0 and 32767.

echo $RANDOM

Exploring and editing the files

Change directory

cd /path/to/directory

List files and directories

ls

Copy files and directories

cp file1 file2

Move or rename files or directories

mv oldfile newfile

Delete files

rm filename

Create a new directory

mkdir new_directory

Get the location of a file

# on git bash
where file_or_executable_append_to_path

#or 
# on ubuntu

whereis file_or_executable_append_to_path)

Flux redirection

Redirect output to a file

echo "Hello, world!" output.txt

Redirect output to a variable

# Store the current date in the 'current_date' variable using command substitution
current_date=$(date)

# Display the result
echo "Current date is: $current_date"

Append output to a file

echo "More text" > output.txt

Pipe the output of one command as the input to another

command1 | command2

This procedure can be useful to chain operations.

Silence the output of a command

Both stdout and stderr (resp. standard output and standard error) can be redirected to /dev/null which is a file that discards data.

Redirect Both stdout and stderr to /dev/null
command /dev/null 2>&1
Redirect only stdout to /dev/null
command /dev/null

Matching strings

Matches any sequence of characters

ls *.txt

Matches any single character

ls file?.txt

Displaying some stuff

Displaying variables

echo variable

Display the content of a file

cat filename

Permissions and ownership

Change file permissions

chmod +x script.sh

Change file ownership.

chown user:group filename

Objects

Variables

variable_name="value"

Arrays

Creation
# Method 1
array=("value1" "value2" "value3")

# Method 2
array[0]="value1"
array[1]="value2"
array[2]="value3"
Accessing
echo ${array[0]}   # prints "value1"
echo ${array[1]}   # prints "value2"
Iterating
array=("value1" "value2" "value3")

for element in "${array[@]}"; do
    echo $element
done
Array length
array=("value1" "value2" "value3")
length=${#array[@]}
echo "Array length: $length"
Appending
array=("value1" "value2")
array+=( "value3" "value4" )
Searching
array=("apple" "orange" "banana")

search_element="orange"
for element in "${array[@]}"; do
    if [ "$element" == "$search_element" ]; then
        echo "Element found: $search_element"
        break
    fi
done
Removing
array=("apple" "orange" "banana")
element_to_remove="orange"

array=("${array[@]/$element_to_remove}")

Functions

function_name() {
    # Code for the function
}

Operators

Comparison Operators

  • -eq: Equal to
  • -ne: Not equal to
  • -lt: Less than
  • -le: Less than or equal to
  • -gt: Greater than
  • -ge: Greater than or equal to

Logical Operators:

  • &&: Logical AND
  • ||: Logical OR
  • !: Logical NOT

Statements

Conditional statements

If
if [ $a -gt $b ]; then
    echo "a is greater than b"
elif [ $a -lt $b ]; then
    echo "a is less than b"
else
    echo "a is equal to b"
fi
case
case $fruit in
    "apple")
        echo "It's an apple"
        ;;
    "orange" | "mandarin")
        echo "It's an orange or mandarin"
        ;;
    *)
        echo "Unknown fruit"
        ;;
esac

Loops

For
for i in {1..5}; do
    echo $i
done
While
count=1
while [ $count -le 5 ]; do
    echo $count
    ((count++))
done
Until
count=1
until [ $count -gt 5 ]; do
    echo $count
    ((count++))
done
Foreach
fruits=("apple" "orange" "banana")

for fruit in "${fruits[@]}"; do
    echo $fruit
done
Break and continue

Exit a loop prematurely using break:

for i in {1..10}; do
    if [ $i -eq 5 ]; then
        break
    fi
    echo $i
done

Skip the rest of the loop code to the next iteration using continue:

for i in {1..5}; do
    if [ $i -eq 3 ]; then
        continue
    fi
    echo $i
done

Input flags handling

Positional arguments

TODO

Conditional arguments

TODO

Script examples

[[Configure and build a CMake solution]] [[Delete a folder properly]] [[Run doxygen on a project]]