Skip to content

Bash Scripting Notes

Shell Parameter Expansion

Shell Parameter Expansion (Bash Reference Manual)

Null and Unset

  • ${parameter:-word}: if (parameter is unset or null) then word else parameter
  • ${parameter:=word}: if (parameter is unset or null) { parameter=word; word } else
  • ${parameter:?word}: if (parameter is unset or null) { print word to stderr; exit 1 } else
  • ${parameter:+word}: if (parameter is unset or null) { null } else

Remove Matching Prefix/Suffix

  • ${parameter#word}: remove smallest matching prefix pattern
  • ${parameter##word}: remove largest matching prefix pattern
  • ${parameter%word}: remove smallest matching suffix pattern
  • ${parameter%%word}: remove largest matching suffix pattern

E.g. file='a/b/file.tar.gz'

  • ${file#*/}: b/file.tar.gz
  • ${file##*/}: file.tar.gz
  • ${file%/*}: a/b
  • ${file%%/*}: a
  • ${file%.*}: a/b/file.tar
  • ${file%%.*}: a/b/file
  • ${file#*.}: tar.gz
  • ${file##*.}: gz

Control Flow

Compound Commands (Bash Reference Manual)

Semicolons are used to separate commands on the same line. They can be replaced with newlines.

  • if condition; then ...; [elif condition; then ...;] [else ...;] fi
  • for var in ...; do ...; done
  • while condition; do ...; done

Conditional Expressions

Conditional Constructs (Bash Reference Manual)Conditional Expressions (Bash Reference Manual)

What's the difference between [ and [[ in Bash? (Stack Overflow)

[[ is bash's improvement to the [ command. It has several enhancements that make it a better choice if you write scripts that target bash. My favorites are:

  • It is a syntactical feature of the shell, so it has some special behavior that [ doesn't have. You no longer have to quote variables like mad because [[ handles empty strings and strings with whitespace more intuitively. For example, with [ you have to write

    bash
    if [ -f "$file" ]

    to correctly handle empty strings or file names with spaces in them. With [[ the quotes are unnecessary:

    bash
    if [[ -f $file ]]
  • Because it is a syntactical feature, it lets you use && and || operators for boolean tests and < and > for string comparisons. [ cannot do this because it is a regular command and &&, ||, <, and > are not passed to regular commands as command-line arguments.

  • It has a wonderful =~ operator for doing regular expression matches. With [ you might write

    bash
    if [ "$answer" = y -o "$answer" = yes ]

    With [[ you can write this as

    bash
    if [[ $answer =~ ^y(es)?$ ]]

    It even lets you access the captured groups which it stores in BASH_REMATCH. For instance, ${BASH_REMATCH[1]} would be "es" if you typed a full "yes" above.

  • You get pattern matching aka globbing for free. Maybe you're less strict about how to type yes. Maybe you're okay if the user types y-anything. Got you covered:

    bash
    if [[ $ANSWER = y* ]]

Functions

  • function_name() { ...; }