Skip to content

Instantly share code, notes, and snippets.

@Uplink03
Created September 15, 2022 23:55
Show Gist options
  • Save Uplink03/927dadadb739ead7c59a4f92d9d1befd to your computer and use it in GitHub Desktop.
Save Uplink03/927dadadb739ead7c59a4f92d9d1befd to your computer and use it in GitHub Desktop.
Bash programming(!) language
#!/bin/bash
# This file is supposed to give you a quick idea about what Bash can do beyond its regular job as a shell or scripting language.
# Bash is more than a scripting language. It's a half-decent programming language. It's snail slow, but half-decent otherwise.
# While it's very archane for such usage, it can be a good substitute for Perl and Python in a pinch.
# These things won't work on cut down shells (e.g. sh, ash, dash), and may explode on ZSH, which has its own,
# somewhat friendlier(!), more modern(!) ways of doing these things.
# Remember kids: always quote your variables in Bash! You're almost certainly expecting them to expand
# to one token, not several and, if you don't quote them, get surprised by spaces in variable values.
declare -A arr=(
[summary]="Bash 4 supports associative arrays!"
[text2]="Text 2"
[text3]="Text 3"
)
echo "Associative array access: ${arr[summary]}"
# Pointers!
# Bash also has "pointers", but it calls them "indirect expansion"
indirect="arr[text2]"
echo "Indirect value: ${!indirect}"
read -r "$indirect" <<<"Updated indirect value"
echo "Updated: ${!indirect}"
# print $arr
declare -p arr
# Performant way to build a string:
# Append to an array of strings then join it together
# Appending to a string to obtain a new one gets slow fast
declare -a items=()
for ((i=0; i<9; i++)); do
# Yes, we expand the array only to set it back in with one more element, but that doesn't have a noticeable
# performance impact, and it's miles faster than doing the same thing with strings
items=("${items[@]}" "item $i")
done
# Joining arrays is archane. We abuse parameter expansion.
# Use use IFS to define the "joining character", but that also means the string can only be one character long.
# I'm using `read` and `Process Substitution` (see man bash) in order to avoid this other pattern:
# OldIFS="$IFS"; IFS=";"; string="${items[*]}"; IFS="$OldIFS"
read -r string < <(IFS=";"; echo "${items[*]}")
echo "Joined string: $string"
# Personal preferences:
# - Use the .bash file extension to make it clear that the script is not meant for non-Bash shells and most like will not work
# - tabs for indentation (I use 8-space tabs, but if you use 4, it's only cosmetic for display, so it's also good)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment