Bash is a common default shell language for many distributions. This course will introduce bash-specific knowledge that should help you write simpler, and maybe better code/commands, using some enhancements introduced with Bash ✨.

Note that the features introduced here shouldn't work on every machine, as they will most likely not use bash (zsh. ash, csh, ksh...).

The man page for bash explains everything about bash, such as environment variables, or control-flow structures...

Some nice information

  • Released in 1989
  • BASH = Bourne-Again SHell
  • Default on Debian and many derivatives, such as Ubuntu

~/.bashrc is a script executed when launching a terminal. You can write alias, permanent changes to environment variables, or builtin inside. You may have to create it. Once you changed its contents, you can update your current terminal using source ~/.bashrc.

Debugging πŸͺ²

$ bash -x
+ echo Toto
+ command -v
+ ls .
# ...

You can use -x to debug your scripts. Each line prefixed with a + is the command executed, then you have the command output. It should help you find the command that failed.

You could also add a breakpoint if you want to only have this feature for a part of your code.

Example of using breakpoints
echo "Not debugged"
set -x # start
echo "Debugged"
set +x # stop
echo "Not debugged"
$ ./
Not debugged
++ echo Debugged
++ set +x
Not debugged

History expansion πŸ•ŠοΈ

Bash introduced some patterns that are expanded into a previous command from your history. Your history of commands is stored in ~/.bash_history

  • nth command in history, starting from 0
$ !n
# if failed:
# -bash: !0: event not found
  • nth command in history, starting from the previous command
$ !-n
  • the previous command, same as !-1
$ !!
  • the most recent command starting with cat
$ !cat
  • the last command containing "hello"
$ !?hello
# add a trailing '?' to explicitly close the query
$ !?hello?

There is also !# which repeats the command-line typed so far. It seems kinda useless from my point of view.

Braces expansion 🍁

This is most likely one of the coolest features, as we can use this everywhere.

  • {0..5} is replaced with "0 1 2 3 4 5"
  • {a..e} is replaced with "a b c d e"
  • {a..e..2} is replaced with "a c e"
  • {toto,tata,titi} is replaced with "toto tata titi"
  • {toto,tata,???} is replaced with "toto tata", and any file matching the glob-pattern "???"

For instance, you can use these in loops, or in glob patterns.

  • Glob-patterns
$ ls *.{jpg,png,gif}
# is the same as
$ ls *.jpg *.png *.gif
  • "for i"
for i in {0..5}; do 
  echo "$i"

Enhanced control-flow structures πŸš€

  • You can use && (AND), and && (OR)
  • You can use >... to compare numbers/strings
if [ 5 > 3 ] || false; then
  echo "ok";

if [[ 5 > 3  || false ]]; then
  echo "ok";
  • You can use "for i, i++"
for (( i = 0; i < 10; i++ )); do
    # code
  • You can use a select statement to select an option
select name in option1 option2 ; do
  # name is either empty or equal to option1/option2,
  # and $REPLY is your REPLY
  echo $name with reply: $REPLY

Arrays πŸ—ƒοΈ

Create an array

$ array=(1 2 3 4 5)

Get a value

$ echo ${array[0]}

Print all values

$ echo ${array[@]}


$ echo ${#array[@]}

Add a value

$ array+=(1)

Set a value

$ array[0]=1

Remove a value

$ unset array[0]

Iterate an array

for i in ${array[@]}; do
  echo $i

Random notes πŸŽ‰

This is a command taking a variable number of parameters, and literally doing nothing

$ :

In bash, doing "< file" is a faster way of doing "cat file", according to the manual

$ < file

Bash introduced a new redirection that takes some text, and redirects it to the standard output

# same as "echo word | command"
$ command <<< word
# same as "cmd1 2>&1 | cmd2"
$ cmd1 |& cmd2 

πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.