Bash Magic

Bash is great. Here is a list of bash tricks & knowledge points that I found magical

Posted by Rico's Nerd Cluster on June 15, 2023

Builtins

Declare

The declare builtin is used to explictly declare variables

  • declare -r var is to declare a read-only variable
1
2
declare -r var="123"
var="456"   # see "var: readonly variable"
  • declare -a indexed_array
  • declare -A associative_array
  • declare -i integer_value

  • declare -x exported_var="exported var" can also define and export a variable

  • It can also print all variable (custom & environment variables) values. declare -p

Though a most variables (except for arrays) can be defined directly VAR=123, I found declare more “type-safe”.

Data Structures

Array

Bash has 1D indexed array (the common array we normally see), and associative array. Any variable can be used as an array. To declare an array, use declare.

Bash Array

An indexed array is “common”. However, it doesn’t guarantee that items are stored contiguously.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
declare -a array1 array2    # one can declare multiple variables
array1=("apple" "peach")
echo ${array1[1]}   # see apple,
echo ${array1[@]}   # see apple,peach
array2=("pear")
# $array2 is the first element in array2 only, similar to c.
# array1+=$array2 #applepear peach 

# This is also applepear peach
# array1+="${array2[@]}"

array1+=("${array2[@]}")    #see apple, peach, pear ?
echo ${array1[@]}   # see apple,peach

array1+=("pecan")   
echo ${array1[@]}   #see apple, peach, pear, pecan

Associative Array

A bash associative array is similar to a python dictionary. E.g., below is an excerpt of a script that downloads ROS bags

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
declare -A bags_link_lookup #?

# This is very dictionary-like
bags_link_lookup["data/rgbd_dataset_freiburg1_xyz.bag"]="https://cvg.cit.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_xyz.bag"
bags_link_lookup["data/rgbd_dataset_freiburg1_rpy.bag"]="https://cvg.cit.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_rpy.bag"

echo "Download bag files if they are missing ..."
for key in "${!bags_link_lookup[@]}"; do
    if [[ -f "${key}" ]]; then 
        echo "No need to download dataset ${key}..."
    else
        echo "Downloading dataset ${key}"
        wget -P data "${bags_link_lookup[$key]}"
    fi
done
echo "Done Downloading"