Basics of Bash Scripting
- Execution of commands and control flow expressions
- Variables, control flow, and unique syntax
- Tailored for shell-related tasks
Variables and Strings in Bash
- Assign with
foo=bar - Access values with
$foo - Differentiating
'and"for strings
foo=bar
echo "$foo" # prints bar
echo '$foo' # prints $fooSpecial Variables in Bash
$0- Name of the script$1to$9- Arguments to the script.$1is the first argument and so on.$@- All the arguments$#- Number of arguments$?- Return code of the previous command$$- Process identification number (PID) for the current script!!- Entire last command, including arguments. A common pattern is to execute a command only for it to fail due to missing permissions; you can quickly re-execute the command with sudo by doingsudo !!$_- Last argument from the last command. If you are in an interactive shell, you can also quickly get this value by typingEscfollowed by.orAlt+.- Comprehensive list: Special Chars in Bash
Command Execution and Return Codes
- Conditional execution with
&&,||,; - Understanding
trueandfalsecommands
false || echo "Oops, fail"
# Oops, fail
true || echo "Will not be printed"
#
true && echo "Things went well"
# Things went well
false && echo "Will not be printed"
#
true ; echo "This will always run"
# This will always run
false ; echo "This will always run"
# This will always runPermissions – brief recap
Unix-like permissions are:
- Read (r): Open and read a file. List contents for directories.
- Write (w): Modify a file’s contents. Add, remove, rename files in directories.
- Execute (x): Execute a file as a program/script. Access or traverse directories.
Grouped by 3 user categories:
- User (u): The owner of the file.
- Group (g): Users in the file’s group.
- Other (o): Users not the owner or in the file’s group.
Default permissions
When a file is created in Unix, default permissions are usually:
- Read and Write for the User (rw-)
- Read for the Group (r—)
- Read for Others (r—)
Depicted as: rw-r--r--
Script Example
- Prefer
[[ ]]for comparisons
#!/bin/bash
echo "Starting program at $(date)" # Date will be substituted
echo "Running program $0 with $# arguments with pid $$"
for file in "$@"; do
grep foobar "$file" > /dev/null 2> /dev/null
# When pattern is not found, grep has exit status 1
# We redirect STDOUT and STDERR to a null register since we do not care about them
if [[ $? -ne 0 ]]; then
echo "File $file does not have any foobar, adding one"
echo "# foobar" >> "$file"
fi
doneCommand substitution using $( CMD )
GNUPGHOME="$(mktemp -d)" && \
export GNUPGHOME && \
for key in \
"B46DC71E03FEEB7F89D1F2491F7A8F87B9D8F501" \
; do \
gpg --batch --keyserver "keyserver.ubuntu.com" --recv-keys "$key" ; \
done && \
gpg --verify "/tmp/$QD_NAME.tar.gz.sha256.asc" "/tmp/$QD_NAME.tar.gz.sha256" && \
(cd /tmp && sha256sum --check --status "$QD_NAME.tar.gz.sha256") && \Control Flow and Functions
- Supports
if,case,while,for - Function example: Creating and entering a directory
mcd () {
mkdir -p "$1"
cd "$1"
}Shell Functions vs Scripts
- Functions are in the shell’s language; scripts can be in any language.
- Functions load once; scripts load each execution.
- Functions can modify the environment; scripts cannot, but receive exported variables.
- Functions promote code modularity, reuse, and clarity, and are often included in scripts.
Bash Comparisons and Globbing
- Globbing with wildcards
?,*, and{}
Shell Tools
Discovering Command Usage
- Using
--help,mancommand, and TLDR pages - Example:
man rm,tldr tar
Finding Files
- Tools:
find,fd,locate - Usage scenarios for each
Finding Code
grepand alternatives likeack,ag,rg- Pattern searching examples
Finding Shell Commands
- Utilizing
history,Ctrl+R,fzfbindings - Autosuggestions and protecting sensitive history entries
Directory Navigation
- Fast navigation with
fasd,autojump - Advanced tools:
tree,broot,nnn,ranger