### Reverse an array in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Demonstrates how to reverse an array in Bash using the `extdebug` option and the `BASH_ARGV` array. Requires enabling `extdebug` and `compat44` in Bash 5.0+. The example includes a function definition and usage examples. ```shell reverse_array() { # Usage: reverse_array "array" shopt -s extdebug f()(printf '%s\n' "${BASH_ARGV[@]}"); f "$@" shopt -u extdebug } ``` ```shell $ reverse_array 1 2 3 4 5 5 4 3 2 1 $ arr=(red blue green) $ reverse_array "${arr[@]}" green blue red ``` -------------------------------- ### Check if string starts with sub-string Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Verifies if a string begins with a specified substring. ```bash # Check if string starts with sub-string string="hello world" substring="hello" if [[ "$string" == "$substring"* ]]; then echo "String starts with substring." else echo "String does not start with substring." fi ``` -------------------------------- ### Get the first N lines of a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Extracts the initial N lines from a given file. ```bash # Get the first N lines of a file N=3 head -n $N filename.txt ``` -------------------------------- ### Example Test Case Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/CONTRIBUTING.md Demonstrates how to write a unit test for a bash function. Tests should be named following the `test_func_name` convention and use `assert_equals` for validation. ```sh test_upper() { result="$(upper "HeLlO")" assert_equals "$result" "HELLO" } ``` -------------------------------- ### Bash Brace Expansion: String Lists Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter9.txt Illustrates how to use brace expansion to create lists of strings and provides a practical example of removing multiple directories using this feature. ```shell echo {apples,oranges,pears,grapes} # Example Usage: # Remove dirs Movies, Music and ISOS from ~/Downloads/. rm -rf ~/Downloads/{Movies,Music,ISOS} ``` -------------------------------- ### Get Operating System Architecture Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Returns the architecture of the operating system, such as x86_64 or arm64. ```shell "$HOSTTYPE" ``` -------------------------------- ### Loop over files and directories in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to loop over files and directories in Bash using a `for` loop and wildcard characters. The example includes looping over all files in the current directory, PNG files in a specific directory, directories in a specific directory, and files using brace expansion. It also demonstrates recursive iteration using `globstar`. ```shell # Greedy example. for file in *; do printf '%s\n' "$file" done # PNG files in dir. for file in ~/Pictures/*.png; do printf '%s\n' "$file" done # Iterate over directories. for dir in ~/Downloads/*/; do printf '%s\n' "$dir" done # Brace Expansion. for file in /path/to/parentdir/{file1,file2,subdir/file3}; do printf '%s\n' "$file" done # Iterate recursively. shopt -s globstar for file in ~/Pictures/**/*; do printf '%s\n' "$file" done shopt -u globstar ``` -------------------------------- ### Get a random array element in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Demonstrates how to retrieve a random element from an array in Bash using the `RANDOM` variable. The example includes a function definition and usage examples. ```shell random_array_element() { # Usage: random_array_element "array" local arr=("$@") printf '%s\n' "${arr[RANDOM % $#]}" } ``` ```shell $ array=(red green blue yellow brown) $ random_array_element "${array[@]}" yellow # Multiple arguments can also be passed. $ random_array_element 1 2 3 4 5 6 7 3 ``` -------------------------------- ### Strip Pattern from Start of String Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md This function removes a pattern from the beginning (left side) of a string. The `lstrip` function takes the input string and the pattern to remove from the start, printing the result. ```bash lstrip() { # Usage: lstrip "string" "pattern" printf '%s\n' "${1##$2}" } ``` -------------------------------- ### Loop over a range of numbers in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Demonstrates how to loop over a range of numbers in Bash using brace expansion and a `for` loop. This example shows how to loop from 0 to 100 and how to loop from 0 to a variable value. ```shell # Loop from 0-100 (no variable support). for i in {0..100}; do printf '%s\n' "$i" done ``` ```shell # Loop from 0-VAR. VAR=50 for ((i=0;i<=VAR;i++)); do printf '%s\n' "$i" done ``` -------------------------------- ### Bash Brace Expansion: Numerical and Alphabetical Ranges Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter9.txt Demonstrates the use of brace expansion to generate sequences of numbers and characters. Includes examples for simple ranges, zero-padded numbers (Bash 4+), and ranges with custom increments (Bash 4+). ```shell # Print numbers 1-100. echo {1..100} # Print range of floats. echo 1.{1..9} # Print chars a-z. echo {a..z} echo {A..Z} # Nesting. echo {A..Z}{0..9} # Print zero-padded numbers. # CAVEAT: bash 4+ echo {01..100} # Change increment amount. # Syntax: {....} # CAVEAT: bash 4+ echo {1..10..2} # Increment by 2. ``` -------------------------------- ### Loop over an array in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to loop over an array in Bash using a `for` loop. The example includes looping over just the elements and looping over both the elements and their indices. ```shell arr=(apples oranges tomatoes) # Just elements. for element in "${arr[@]}"; do printf '%s\n' "$element" done ``` ```shell arr=(apples oranges tomatoes) # Elements and index. for i in "${!arr[@]}"; do printf '%s\n' "${arr[i]}" done # Alternative method. for ((i=0;i<${#arr[@]};i++)); do printf '%s\n' "${arr[i]}" done ``` -------------------------------- ### Bash Traps for Signal Handling Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Explains how to use the `trap` command in bash to execute code in response to various signals. Examples include executing code on script exit, ignoring terminal interrupts (SIGINT), reacting to window resize (SIGWINCH), executing code before every command (DEBUG), and executing code when a function or sourced file finishes (RETURN). ```shell # Clear screen on script exit. trap 'printf \e[2J\e[H\e[m' EXIT trap '' INT # Call a function on window resize. trap 'code_here' SIGWINCH trap 'code_here' DEBUG trap 'code_here' RETURN ``` -------------------------------- ### Strip pattern from start of string Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Removes a specified pattern if it appears at the beginning of a string. ```bash # Strip pattern from start of string string="prefix_hello_world" pattern="prefix_" stripped_string="${string#${pattern}}" echo "${stripped_string}" ``` -------------------------------- ### Get System Hostname Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Retrieves the hostname of the system. It includes a fallback to the `hostname` command if the variable is empty. ```shell "$HOSTNAME" # NOTE: This variable may be empty. # Optionally set a fallback to the hostname command. "${HOSTNAME:-$(hostname)}" ``` -------------------------------- ### Get the first N lines of a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter4.txt A Bash function to retrieve the first N lines of a file, serving as a pure Bash alternative to the `head` command. Requires Bash 4+. ```shell head() { # Usage: head "n" "file" mapfile -tn "$1" line < "$2" printf '%s\n' "${line[@]}" } ``` -------------------------------- ### Cycle through an array in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to cycle through an array in Bash, printing each element in sequence and then restarting from the beginning. This example uses a global index variable to keep track of the current position in the array. ```shell arr=(a b c d) cycle() { printf '%s ' "${arr[${i:=0}]}" ((i=i>=${#arr[@]}-1?0:++i)) } ``` -------------------------------- ### Bash Parameter Expansion: Length Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to get the length of a variable or an array using bash parameter expansion. ```bash # Length # Length of var in characters # Example: var="hello"; echo "${#var}" # Output: 5 # Length of array in elements # Example: arr=("a" "b" "c"); echo "${#arr[@]}" # Output: 3 ``` -------------------------------- ### Check if String Starts with Substring Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter1.txt Checks if a given string begins with a specific substring using Bash's pattern matching within conditional expressions. ```shell if [[ $var == sub_string* ]]; then printf '%s\n' "var starts with sub_string." fi # Inverse (var does not start with sub_string). if [[ $var != sub_string* ]]; then printf '%s\n' "var does not start with sub_string." fi ``` -------------------------------- ### Use regex on a string Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter1.txt Applies a regular expression to a string and prints the first matching capture group. This function can replace sed for many use cases but is platform-dependent on the installed regex engine. ```bash regex() { # Usage: regex "string" "regex" [[ $1 =~ $2 ]] && printf '%s\n' "${BASH_REMATCH[1]}" } ``` -------------------------------- ### Get Current Working Directory Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Retrieves the current working directory. This serves as an alternative to the `pwd` built-in command. ```shell "$PWD" ``` -------------------------------- ### Get the first N lines of a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md A bash function to replicate the `head` command's functionality, retrieving the first N lines of a file. Requires bash 4+. ```shell head() { # Usage: head "n" "file" mapfile -tn "$1" line < "$2" printf '%s\n' "${line[@]}" } ``` -------------------------------- ### Get Bash Version Information Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Provides the version of the currently running Bash process. It can be accessed as a string or an array for detailed version components. ```shell # As a string. "$BASH_VERSION" ``` ```shell # As an array. "${BASH_VERSINFO[@]}" ``` -------------------------------- ### Strip Pattern from Start of String Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter1.txt Removes a specified pattern from the beginning of a given string. It utilizes Bash's parameter expansion for efficient string manipulation. ```shell lstrip() { # Usage: lstrip "string" "pattern" printf '%s\n' "${1##$2}" } ``` -------------------------------- ### Check if a program is in the user's PATH Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter19.txt Provides three methods (type -p, hash, command -v) to check if an executable is available in the system's PATH. Includes examples for conditional execution and early exit if a program is not found. ```sh # There are 3 ways to do this and either one can be used. type -p executable_name &>/dev/null hash executable_name &>/dev/null command -v executable_name &>/dev/null # As a test. if type -p executable_name &>/dev/null; # Program is in PATH. fi # Inverse. if ! type -p executable_name &>/dev/null; # Program is not in PATH. fi # Example (Exit early if program is not installed). if ! type -p convert &>/dev/null; printf '%s\n' "error: convert is not installed, exiting..." exit 1 fi ``` -------------------------------- ### Use Regex on a String Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md This function demonstrates using bash's built-in regex matching to extract captured groups from a string. It's a platform-dependent feature that relies on the system's regex engine. The example function `regex` takes a string and a regex pattern, returning the first captured group. ```bash regex() { # Usage: regex "string" "regex" [[ $1 =~ $2 ]] && printf '%s\n' "${BASH_REMATCH[1]}" } ``` -------------------------------- ### Get the number of lines in a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter4.txt Provides pure Bash functions to count the number of lines in a file, as an alternative to `wc -l`. Includes a Bash 4+ `mapfile` version and a Bash 3 compatible loop version. ```shell # Example Function (bash 4): lines() { # Usage: lines "file" mapfile -tn 0 lines < "$1" printf '%s\n' "${#lines[@]}" } # Example Function (bash 3): lines_loop() { # Usage: lines_loop "file" count=0 while IFS= read -r _; do ((count++)) done < "$1" printf '%s\n' "$count" } ``` -------------------------------- ### Ignored Code Blocks Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/CONTRIBUTING.md Code blocks marked with 'shell' are intended for examples or syntax that should not be linted or tested. This is useful for demonstrating specific shell features or shorthand. ```shell # Shorter file creation syntax. :>file ``` -------------------------------- ### Create an empty file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter4.txt Demonstrates multiple pure Bash methods for creating an empty file, serving as alternatives to the `touch` command. Includes the shortest syntax `>file`. ```shell # Shortest. >file # Longer alternatives: :>file echo -n >file printf '' >file ``` -------------------------------- ### Check if a string starts or ends with a substring in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to check if a string starts or ends with a specific substring using the `[[ ]]` test in Bash. The `==` operator with wildcard characters is used to match the beginning or end of the string. Includes inverse checks to determine if a string does not start or end with a substring. ```shell if [[ $var == sub_string* ]]; then printf '%s\n' "var starts with sub_string." fi # Inverse (var does not start with sub_string). if [[ $var != sub_string* ]]; then printf '%s\n' "var does not start with sub_string." fi ``` ```shell if [[ $var == *sub_string ]]; then printf '%s\n' "var ends with sub_string." fi # Inverse (var does not end with sub_string). if [[ $var != *sub_string ]]; then printf '%s\n' "var does not end with sub_string." fi ``` -------------------------------- ### Shorter Bash 'for' Loop Syntaxes Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter18.txt Demonstrates various concise syntaxes for 'for' loops in Bash, including C-style loops, undocumented methods, and expansion techniques for iterating through sequences. ```shell # Tiny C Style. for((;i++<10;)){ echo "$i";} # Undocumented method. for i in {1..10};{ echo "$i";} # Expansion. for i in {1..10}; do echo "$i"; done # C Style. for((i=0;i<=10;i++)); do echo "$i"; done ``` -------------------------------- ### Running Tests and Shellcheck Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/CONTRIBUTING.md This snippet shows the command to execute the test script, which also runs Shellcheck on the project's code. Ensure you are in the project directory before running. ```bash cd pure-bash-bible ./test.sh ``` -------------------------------- ### Get the list of functions in a script Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter19.txt A Bash function that lists all declared functions within the current script. It uses 'declare -F' to get the function names and then formats the output. ```sh get_functions() { # Usage: get_functions IFS=$'\n' read -d "" -ra functions < <(declare -F) printf '%s\n' "${functions[@]//declare -f }" } ``` -------------------------------- ### Shorter Bash Infinite Loop Syntaxes Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter18.txt Presents more compact ways to create infinite loops in Bash compared to the standard 'while :;' syntax. It includes C-style and other efficient methods. ```shell # Normal method while :; do echo hi; done # Shorter for((;;)){ echo hi;} ``` -------------------------------- ### Remove duplicate array elements in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to remove duplicate elements from an array in Bash using an associative array. Requires Bash 4+. The example includes a function definition and usage examples. Note that the list order may not be preserved. ```shell remove_array_dups() { # Usage: remove_array_dups "array" declare -A tmp_array for i in "$@"; do [[ $i ]] && IFS=" " tmp_array["${i:- }"]=1 done printf '%s\n' "${!tmp_array[@]}" } ``` ```shell $ remove_array_dups 1 1 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5 1 2 3 4 5 $ arr=(red red green blue blue) $ remove_array_dups "${arr[@]}" red green blue ``` -------------------------------- ### Create an empty file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Provides several pure bash methods to create an empty file, serving as an alternative to the `touch` command. ```shell # Shortest. >file # Longer alternatives: :>file echo -n >file printf '' >file ``` -------------------------------- ### Get the number of lines in a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Counts the total number of lines present in a file. ```bash # Get the number of lines in a file line_count=$(wc -l < filename.txt) echo "Number of lines: $line_count" ``` -------------------------------- ### Shorter `for` Loop Syntax Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Demonstrates various concise syntaxes for `for` loops in bash, including C-style and brace expansion. ```bash # Tiny C Style. for((;i++<10;)){ echo "$i";} # Undocumented method. for i in {1..10};{ echo "$i";} # Expansion. for i in {1..10}; do echo "$i"; done # C Style. for((i=0;i<=10;i++)); do echo "$i"; done ``` -------------------------------- ### Alternative to sleep using read Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter19.txt Demonstrates using the 'read' command with a timeout as an alternative to the 'sleep' command. This method avoids spawning an external process. Requires Bash 4+. ```sh read_sleep() { # Usage: read_sleep 1 # read_sleep 0.2 read -rt "$1" <> <(:) || : } # Example Usage: read_sleep 1 read_sleep 0.1 read_sleep 30 ``` ```sh exec {sleep_fd}<> <(:) while some_quick_test; do # equivalent of sleep 0.001 read -t 0.001 -u $sleep_fd done ``` -------------------------------- ### Loop over a variable range of numbers Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Iterates through numbers where the start and end points are defined by variables. ```bash # Loop over a variable range of numbers start=3 end=7 for (( i=$start; i<=$end; i++ )); do echo "Number: $i" done ``` -------------------------------- ### Get Username Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Retrieves the username of the current user using printf. Requires bash 4.4+. ```bash # $ : \u # Expand the parameter as if it were a prompt string. # $ printf '%s\n' "${_@P}" # black ``` -------------------------------- ### String Lists Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Creates combinations of strings using brace expansion. ```bash # String Lists echo file_{a,b,c}.txt echo {start,middle,end}_section ``` -------------------------------- ### Get the base-name of a file path Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Retrieves the filename (without the directory path) from a file path. ```bash # Get the base-name of a file path filepath="/home/user/documents/report.txt" base_name=$(basename "$filepath") echo "Base name: $base_name" ``` -------------------------------- ### Loop Over Files and Directories Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter3.txt Demonstrates various methods for iterating over files and directories using globbing patterns. Includes greedy matching, specific file types, subdirectories, brace expansion, and recursive globbing with `globstar`. ```shell # Greedy example. for file in *; do printf '%s\n' "$file" done # PNG files in dir. for file in ~/Pictures/*.png; do printf '%s\n' "$file" done # Iterate over directories. for dir in ~/Downloads/*/; do printf '%s\n' "$dir" done # Brace Expansion. for file in /path/to/parentdir/{file1,file2,subdir/file3}; do printf '%s\n' "$file" done # Iterate recursively. shopt -s globstar for file in ~/Pictures/**/*; do printf '%s\n' "$file" done shopt -u globstar ``` -------------------------------- ### Get the directory name of a file path Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Extracts the directory portion from a given file path. ```bash # Get the directory name of a file path filepath="/home/user/documents/report.txt" directory_name=$(dirname "$filepath") echo "Directory: $directory_name" ``` -------------------------------- ### Shorter Bash Function Declaration Syntaxes Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter18.txt Illustrates various condensed methods for declaring functions in Bash, including using subshells, arithmetic expansion, and conditional statements for brevity. ```shell # Normal method f(){ echo hi;} # Using a subshell f()(echo hi) # Using arithmetic # This can be used to assign integer values. # Example: f a=1 # f a++ f()(($1)) # Using tests, loops etc. # NOTE: ‘while’, ‘until’, ‘case’, ‘(())’, ‘[[]]’ can also be used. f()if true; then echo "$1"; fi f()for i in "$@"; do echo "$i"; done ``` -------------------------------- ### Get the last N lines of a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Retrieves the final N lines from a specified file. ```bash # Get the last N lines of a file N=3 tail -n $N filename.txt ``` -------------------------------- ### Create an empty file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Generates a new, empty file. ```bash # Create an empty file touch new_empty_file.txt ``` -------------------------------- ### Shorter Infinite Loops Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Presents more compact ways to create infinite loops in bash using `while` and C-style `for` loops. ```bash # Normal method while :; do echo hi; done # Shorter for((;;)){ echo hi;} ``` -------------------------------- ### Get Script Runtime in Seconds Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Returns the number of seconds the current script has been running. ```shell "$SECONDS" ``` -------------------------------- ### Get List of Functions in a Script Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md A bash function to retrieve and print all declared functions within the current script. ```bash get_functions() { # Usage: get_functions IFS=$'\n' read -d "" -ra functions < <(declare -F) printf '%s\n' "${functions[@]//declare -f }" } ``` -------------------------------- ### Bitwise Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md No description -------------------------------- ### Get a Random Array Element in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter2.txt Selects and prints a random element from an array using the `RANDOM` variable. ```bash random_array_element() { # Usage: random_array_element "array" local arr=($"@") printf '%s\n' "${arr[RANDOM % $#]}" } ``` -------------------------------- ### Bash Parameter Expansion - Default Values Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Demonstrates how to provide default values for shell variables if they are unset or empty. This is useful for setting default configurations or handling optional parameters. ```shell `${VAR:-STRING}`: If VAR is empty or unset, use STRING as its value. `${VAR-STRING}`: If VAR is unset, use STRING as its value. `${VAR:=STRING}`: If VAR is empty or unset, set the value of VAR to STRING. `${VAR=STRING}`: If VAR is unset, set the value of VAR to STRING. `${VAR:+STRING}`: If VAR is not empty, use STRING as its value. `${VAR+STRING}`: If VAR is set, use STRING as its value. `${VAR:?STRING}`: Display an error if empty or unset. `${VAR?STRING}`: Display an error if unset. ``` -------------------------------- ### Get Pseudorandom Integer Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Generates a pseudorandom integer between 0 and 32767. This variable is not suitable for security-sensitive operations. ```shell "$RANDOM" ``` -------------------------------- ### Get the username of the current user Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter19.txt Retrieves the username of the current user by expanding a parameter as if it were a prompt string. Requires Bash 4.4+. ```sh $ : \u # Expand the parameter as if it were a prompt string. $ printf '%s\n' "${_@P}" black ``` -------------------------------- ### Shorter Bash 'if' Statement Syntaxes Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter18.txt Demonstrates concise ways to write 'if' statements in Bash, including single-line conditional execution with '&&' and '||', and multi-line structures without explicit 'if' keywords. ```shell # One line # Note: The 3rd statement may run when the 1st is true [[ $var == hello ]] && echo hi || echo bye [[ $var == hello ]] && { echo hi; echo there; } || echo bye # Multi line (no else, single statement) # Note: The exit status may not be the same as with an if statement [[ $var == hello ]] && echo hi # Multi line (no else) [[ $var == hello ]] && { echo hi # ... } ``` -------------------------------- ### Get Bash Binary Location Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Retrieves the path to the bash binary. This is a fundamental variable for executing bash scripts. ```shell "$BASH" ``` -------------------------------- ### Get Cursor Position Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Obtains the current cursor position (X and Y coordinates) within the terminal, useful for creating TUI applications in bash. ```bash get_cursor_pos() { # Usage: get_cursor_pos IFS='[;' read -p $'e[6n' -d R -rs _ y x _ printf '%s\n' "$x $y" } ``` -------------------------------- ### Bash Brace Expansion - String Lists Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Shows how to use brace expansion to expand a list of strings. This is commonly used for operations on multiple items, such as deleting directories. ```shell echo {apples,oranges,pears,grapes} # Example Usage: # Remove dirs Movies, Music and ISOS from ~/Downloads/. rm -rf ~/Downloads/{Movies,Music,ISOS} ``` -------------------------------- ### Get Current Date with strftime Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Retrieves the current date using bash's printf command with strftime formatting. Requires bash 4+. ```bash date() { # Usage: date "format" # See: 'man strftime' for format. printf "%($1)T\n" "-1" } # Example Usage: # $ date "%a %d %b - %l:%M %p" # Fri 15 Jun - 10:00 AM # Using printf directly. # $ printf '%(%a %d %b - %l:%M %p)T\n' "-1" # Fri 15 Jun - 10:00 AM # Assigning a variable using printf. # $ printf -v date '%(%a %d %b - %l:%M %p)T\n' '-1' # $ printf '%s\n' "$date" # Fri 15 Jun - 10:00 AM ``` -------------------------------- ### Modern Bash Shebang Syntax Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Recommends using `#!/usr/bin/env bash` over `#!/bin/bash` for the shebang line, as it searches the user's PATH for the bash binary, improving portability. ```shell # Right: #!/usr/bin/env bash # Less right: #!/bin/bash ``` -------------------------------- ### Get Terminal Size Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Retrieves the terminal size (lines and columns) using ANSI escape codes. Note that this may not work in all terminal emulators. ```bash get_window_size() { # Usage: get_window_size printf '%b' "${TMUX:+\ePtmux;\e}\e[14t${TMUX:+\e\\}" IFS=';t' read -d t -t 0.05 -sra term_size printf '%s\n' "${term_size[1]}x${term_size[2]}" } ``` -------------------------------- ### Shebang Syntax Comparison Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter15.txt Compares the recommended `#!/usr/bin/env bash` shebang with the less portable `#!/bin/bash`. The former uses the PATH to locate the bash executable, ensuring greater compatibility across different systems. ```shell # Right: #!/usr/bin/env bash # Less right: #!/bin/bash ``` -------------------------------- ### Get the number of lines in a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Calculates the number of lines in a file, serving as an alternative to `wc -l`. Provides implementations for bash 4 and bash 3. ```shell # Example Function (bash 4): lines() { # Usage: lines "file" mapfile -tn 0 lines < "$1" printf '%s\n' "${#lines[@]}" } # Example Function (bash 3): lines_loop() { # Usage: lines_loop "file" count=0 while IFS= read -r _; do ((count++)) done < "$1" printf '%s\n' "$count" } ``` -------------------------------- ### React to Window Resize (SIGWINCH) Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter13.txt This trap executes a specified command or function when the terminal window is resized. It's commonly used to redraw the user interface in terminal applications. ```shell # Call a function on window resize. trap 'code_here' SIGWINCH ``` -------------------------------- ### Get Current and Parent Function Names Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Retrieves the name of the current function and its parent functions. This is useful for debugging and understanding call stacks. ```shell # Current function. "${FUNCNAME[0]}" # Parent function. "${FUNCNAME[1]}" # So on and so forth. "${FUNCNAME[2]}" "${FUNCNAME[3]}" # All functions including parents. "${FUNCNAME[@]}" ``` -------------------------------- ### Bash Parameter Expansion: Replacement Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Illustrates bash parameter expansion for string replacement and pattern removal. Supports removing shortest/longest matches from the start/end of a string and replacing/removing patterns. ```bash # Replacement # Remove shortest match of PATTERN from start of string # Example: var="abcde"; echo "${var#ab}" # Output: cde # Remove longest match of PATTERN from start of string # Example: var="ababcd"; echo "${var##ab}" # Output: cd # Remove shortest match of PATTERN from end of string # Example: var="abcde"; echo "${var%de}" # Output: abc # Remove longest match of PATTERN from end of string # Example: var="abcdcd"; echo "${var%%cd}" # Output: ab # Replace first match with string # Example: var="ababcd"; echo "${var/ab/XX}" # Output: XXabcd # Replace all matches with string # Example: var="ababcd"; echo "${var//ab/XX}" # Output: XXXXcd # Remove first match # Example: var="ababcd"; echo "${var/ab}" # Output: abcd # Remove all matches # Example: var="ababcd"; echo "${var//ab}" # Output: cd ``` -------------------------------- ### Get Operating System/Kernel Name Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Provides the name of the operating system or kernel, useful for OS-specific conditional logic without calling `uname`. ```shell "$OSTYPE" ``` -------------------------------- ### Use regex on a string Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Applies a regular expression to a string for pattern matching and replacement. ```bash # Use regex on a string string="hello world 123" # Replace all digits with 'X' regex_replaced="${string//[0-9]/X}" echo "${regex_replaced}" ``` -------------------------------- ### Loop over the contents of a file in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Demonstrates how to loop over the contents of a file in Bash using a `while` loop and the `read` command. Each line of the file is read into the `line` variable and then printed. ```shell while read -r line; do printf '%s\n' "$line" done < "file" ``` -------------------------------- ### Loop over files and directories Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Iterates through files and directories within a specified directory. ```bash # Loop over files and directories for item in *; do if [[ -f "$item" ]]; then echo "File: $item" elif [[ -d "$item" ]]; then echo "Directory: $item" fi done ``` -------------------------------- ### Get the base-name of a file path Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md A bash function that replicates the `basename` command, extracting the filename from a path and optionally removing a suffix. It handles paths with and without suffixes. ```shell basename() { # Usage: basename "path" ["suffix"] local tmp tmp=${1%"${1##*[!/]}"} tmp=${tmp##*/} tmp=${tmp%"${2/"$tmp"}"} printf '%s\n' "${tmp:-/}" } ``` -------------------------------- ### Simpler Bash 'case' Statement for Variable Assignment Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter18.txt Shows how to use the ':' built-in command within a Bash 'case' statement to efficiently assign values to a variable based on conditions, leveraging the $_ variable. ```shell # Modified snippet from Neofetch. case "$OSTYPE" in "darwin"*) : "MacOS" ;; "linux"*) : "Linux" ;; *"bsd"* | "dragonfly" | "bitrig") : "BSD" ;; "cygwin" | "msys" | "win32") : "Windows" ;; *) printf '%s\n' "Unknown OS detected, aborting..." >&2 exit 1 ;; esac # Finally, set the variable. os="$_" ``` -------------------------------- ### Get the last N lines of a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md A bash function to replicate the `tail` command's functionality, retrieving the last N lines of a file. Requires bash 4+. ```shell tail() { # Usage: tail "n" "file" mapfile -tn 0 line < "$2" printf '%s\n' "${line[@]: -$1}" } ``` -------------------------------- ### Get the directory name of a file path Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md A bash function that mimics the `dirname` command, extracting the directory portion from a given file path. It handles trailing slashes and root directory cases. ```shell dirname() { # Usage: dirname "path" local tmp=${1:-.} [[ $tmp != *[!/]* ]] && { printf '/\n' return } tmp=${tmp%%"${tmp##*[!/]}"} [[ $tmp != */* ]] && { printf '.\n' return } tmp=${tmp%/*} tmp=${tmp%%"${tmp##*[!/]}"} printf '%s\n' "${tmp:-/}" } ``` -------------------------------- ### Open User's Preferred Text Editor Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter16.txt Opens the user's preferred text editor with a specified file. It includes a fallback mechanism if the EDITOR variable is not set. ```shell "$EDITOR" "$file" # NOTE: This variable may be empty, set a fallback value. "${EDITOR:-vi}" "$file" ``` -------------------------------- ### File Comparisons Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Compares files based on modification time or size. ```bash # File Comparisons file1="fileA.txt" file2="fileB.txt" # Check if file1 is newer than file2 if [[ "$file1" -nt "$file2" ]]; then echo "$file1 is newer than $file2." fi # Check if file1 is older than file2 if [[ "$file1" -ot "$file2" ]]; then echo "$file1 is older than $file2." fi ``` -------------------------------- ### Ranges Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Generates sequences of numbers or characters using brace expansion. ```bash # Ranges # Numeric range echo {1..5} # Character range echo {a..e} ``` -------------------------------- ### Toggle between two values Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Switches between two predefined values on each execution. ```bash # Toggle between two values value1="on" value2="off" # Using a variable to keep track of the current state current_state=${current_state:-$value1} if [[ "$current_state" == "$value1" ]]; then current_state="$value2" else current_state="$value1" fi echo "Current state: $current_state" ``` -------------------------------- ### Bash Brace Expansion - Ranges Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Illustrates the use of brace expansion to generate sequences of numbers or characters. This feature simplifies the creation of repetitive patterns. ```shell # Print numbers 1-100. echo {1..100} # Print range of floats. echo 1.{1..9} # Print chars a-z. echo {a..z} echo {A..Z} # Nesting. echo {A..Z}{0..9} # Print zero-padded numbers. # CAVEAT: bash 4+ echo {01..100} # Change increment amount. # Syntax: {....} # CAVEAT: bash 4+ echo {1..10..2} # Increment by 2. ``` -------------------------------- ### Get the last N lines of a file Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter4.txt A Bash function to retrieve the last N lines of a file, acting as a pure Bash replacement for the `tail` command. Requires Bash 4+. ```shell tail() { # Usage: tail "n" "file" mapfile -tn 0 line < "$2" printf '%s\n' "${line[@]: -$1}" } ``` -------------------------------- ### Getting Terminal Size in Bash Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/README.md Provides a bash function `get_term_size` to retrieve the terminal's dimensions (lines and columns) without relying on external commands like `stty` or `tput`. It utilizes the `checkwinsize` shell option. ```shell get_term_size() { # Usage: get_term_size # (:;:) is a micro sleep to ensure the variables are # exported immediately. shopt -s checkwinsize; (:;:) printf '%s\n' "$LINES $COLUMNS" } ``` -------------------------------- ### Get the current date using printf strftime Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter19.txt Utilizes Bash's built-in 'printf' command with strftime formatting to obtain the current date and time, serving as an alternative to the 'date' command. Requires Bash 4+. ```sh date() { # Usage: date "format" # See: 'man strftime' for format. printf "%($1)T\n" "-1" } # Using above function. $ date "%a %d %b - %l:%M %p" Fri 15 Jun - 10:00 AM # Using printf directly. $ printf '%(%a %d %b - %l:%M %p)T\n' "-1" Fri 15 Jun - 10:00 AM # Assigning a variable using printf. $ printf -v date '%(%a %d %b - %l:%M %p)T\n' '-1' $ printf '%s\n' "$date" Fri 15 Jun - 10:00 AM ``` -------------------------------- ### Bash Text Colors using ANSI Escape Sequences Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter7.txt Demonstrates how to set text foreground and background colors using ANSI escape sequences. Supports 256-color mode and True-Color (RGB). Sequences require specific terminal emulator support for RGB. ```bash # Set text foreground color (256 colors) # Example: Set foreground to color number 16 printf "\e[38;5;16mHello\e[0m\n" # Set text background color (256 colors) # Example: Set background to color number 232 printf "\e[48;5;232mWorld\e[0m\n" # Set text foreground color to RGB # Example: Set foreground to a shade of blue (R=0, G=0, B=255) printf "\e[38;2;0;0;255mBlue Text\e[0m\n" # Set text background color to RGB # Example: Set background to a shade of green (R=0, G=255, B=0) printf "\e[48;2;0;255;0mGreen Background\e[0m\n" # Reset all formatting and colors printf "\e[0m" ``` -------------------------------- ### Bash Arithmetic Operations Source: https://github.com/dylanaraps/pure-bash-bible/blob/master/manuscript/chapter12.txt Demonstrates basic arithmetic operations in Bash using the double parenthesis syntax. This includes simple addition, incrementing, decrementing, and using existing variables and array elements in calculations. ```shell ((var=1+2)) ((var++)) ((var--)) ((var+=1)) ((var-=1)) ((var=var2*arr[2])) ```