Bash
Bash is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell.
No commands found
Try adjusting your search term
Getting Started
Fundamental Bash concepts and syntax for beginners.
Simple Script
Illustrates a basic Bash script structure and execution.
Basic script with variable
A basic Bash script that declares a variable and prints a greeting.
#!/bin/bash
VAR="world"echo "Hello $VAR!"bash ./script.shHello world!- The shebang (#!/bin/bash) specifies the Bash interpreter.
- Variables are assigned without spaces around '='.
Script with error handling
Uses 'set -e' to exit on errors and a default variable value if no argument is provided.
#!/bin/bash
set -eVAR="${1:-world}"echo "Hello $VAR!"bash ./script.sh universeuniverseHello universe!- The 'set -e' ensures the script stops on any error.
- Use ${VAR:-default} for fallback values.
Script Arguments
How to handle command-line arguments in Bash scripts.
Accessing positional arguments
Demonstrates accessing script name ($0), positional arguments ($1, $2), and argument count ($#).
#!/bin/bashecho "Script: $0"echo "First arg: $1"echo "Second arg: $2"echo "Total args: $#"bash ./args.sh hello worldhello worldScript: ./args.shFirst arg: helloSecond arg: worldTotal args: 2- Quote arguments with spaces to treat as single arguments.
- Use ${N} for arguments beyond $9.
Iterating over arguments
Uses $@ to iterate over arguments, preserving spaces.
#!/bin/bashfor arg in "$@"; do echo "Argument: $arg"donebash ./loop_args.sh "first arg" secondfirst arg secondArgument: first argArgument: second- Use "$@" to handle arguments with spaces correctly.
Functions
Defining and using functions in Bash scripts.
Basic function definition
Defines a simple function to greet a user.
#!/bin/bash
function greet() { echo "Hello, $1!"}
greet "world"bash ./greet.shHello, world!- 'function' keyword is optional in Bash.
Function with local variables
Demonstrates using local variables within a function.
#!/bin/bash
function add() { local sum=$(( $1 + $2 )) echo "Sum: $sum"}
add 5 10bash ./add.shSum: 15- 'local' restricts the variable scope to the function.
Function with return status
Checks if a number is even using return status.
#!/bin/bash
function check_even() { if (( $1 % 2 == 0 )); then return 0 else return 1 fi}
check_even 4if [ $? -eq 0 ]; then echo "Even"else echo "Odd"fibash ./check_even.shEven- $? captures the exit status of the last command.
Comments
Adding comments in Bash scripts for clarity.
Single-line comment
Demonstrates a single-line comment in Bash.
# This is a single-line comment- Use '#' for single-line comments.
Multi-line comment
':' allows for multi-line comments.
: 'This is amulti-line comment'- Use ': ' for multi-line comments.
Variables
Understanding and using variables in Bash scripts.
Declaring a variable
Declares a variable and prints its value.
#!/bin/bash
VAR="Hello"echo "$VAR"bash ./var.shHello- Use double quotes to prevent word splitting.
Conditionals
Using if-else statements in Bash scripts.
Basic if statement
Checks if a string is empty or not using if-else statements.
#!/bin/bash
if [[ -z "$string" ]]; then echo "String is empty"elif [[ -n "$string" ]]; then echo "String is not empty"fi- Use [[ ]] for conditional expressions.
- Use -z to check if a string is empty.
Shell Execution
Executing shell commands from within a Bash script.
Executing a command
Executes the 'ls -l' command to list files in long format.
#!/bin/bash
ls -lbash ./exec.shtotal 0-rw-r--r-- 1 user group 0 Mar 15 12:00 file.txt- Use backticks or $() for command substitution.
Loops
Iterating over data and controlling loop flow in Bash.
For Loops
Iterating over lists, ranges, and using C-style for loops.
Basic for loop over files
Iterates over all files matching the glob pattern /etc/rc.* and prints each one.
#!/bin/bash
for i in /etc/rc.*; do echo "$i"donebash ./for_files.sh/etc/rc.common/etc/rc.local- Glob patterns are expanded by the shell before the loop runs.
- Always quote variables inside loops to handle spaces in filenames.
C-like for loop
Uses C-style syntax with double parentheses for arithmetic-based loops.
#!/bin/bash
for ((i = 0; i < 5; i++)); do echo "Index: $i"donebash ./c_for.shIndex: 0Index: 1Index: 2Index: 3Index: 4- Double parentheses (( )) allow arithmetic expressions.
- Variables inside (( )) do not need the $ prefix.
Range loop
Uses brace expansion to generate a sequence from 1 to 5.
#!/bin/bash
for i in {1..5}; do echo "Number: $i"donebash ./range.shNumber: 1Number: 2Number: 3Number: 4Number: 5- Brace expansion does not work with variables; use seq or C-style loops instead.
Range loop with step size
Generates a range from 5 to 50 with a step size of 5.
#!/bin/bash
for i in {5..50..5}; do echo "$i"donebash ./range_step.sh5101520253035404550- The syntax is {start..end..step}.
- Step size requires Bash 4.0 or newer.
While Loops
Repeating commands while a condition is true.
Basic while loop
Loops while count is less than 5, incrementing each iteration.
#!/bin/bash
count=0while [[ $count -lt 5 ]]; do echo "Count: $count" ((count++))donebash ./while.shCount: 0Count: 1Count: 2Count: 3Count: 4- Use [[ ]] for conditional tests in while loops.
- (( )) is used for arithmetic increment.
Reading lines from a file
Reads a file line by line using input redirection.
#!/bin/bash
while read -r line; do echo "Line: $line"done < file.txtbash ./read_lines.shLine: first lineLine: second line- The -r flag prevents backslash interpretation.
- Input redirection < feeds the file into the while loop.
Infinite loop
Runs indefinitely until interrupted with Ctrl+C.
#!/bin/bash
while true; do echo "Press Ctrl+C to stop" sleep 1donebash ./infinite.shPress Ctrl+C to stopPress Ctrl+C to stop- Use 'break' inside the loop to exit based on a condition.
- Always include a sleep or wait to prevent CPU overuse.
Loop Control
Controlling loop execution with break, continue, and select.
Using break and continue
Skips 5 with continue and exits the loop at 8 with break.
#!/bin/bash
for i in {1..10}; do if [[ $i -eq 5 ]]; then continue fi if [[ $i -eq 8 ]]; then break fi echo "Number: $i"donebash ./control.shNumber: 1Number: 2Number: 3Number: 4Number: 6Number: 7- continue skips to the next iteration.
- break exits the loop entirely.
Select menu
Presents a numbered menu and executes the corresponding action.
#!/bin/bash
select option in "Start" "Stop" "Quit"; do case $option in "Start") echo "Starting..." ;; "Stop") echo "Stopping..." ;; "Quit") break ;; *) echo "Invalid option" ;; esacdonebash ./select.sh11) Start2) Stop3) Quit#? Starting...- select automatically generates a numbered menu.
- Use break to exit the select loop.
Arrays
Working with indexed arrays in Bash.
Defining Arrays
Creating and initializing indexed arrays in Bash.
Defining an array
Defines an indexed array with three elements and prints each one.
#!/bin/bash
Fruits=('Apple' 'Banana' 'Orange')echo "${Fruits[0]}"echo "${Fruits[1]}"echo "${Fruits[2]}"bash ./array.shAppleBananaOrange- Array indices start at 0 in Bash.
- Elements are separated by spaces inside parentheses.
Index assignment
Assigns values to specific indices; indices do not need to be contiguous.
#!/bin/bash
Fruits[0]="Apple"Fruits[1]="Banana"Fruits[5]="Orange"echo "${Fruits[@]}"bash ./index_assign.shApple Banana Orange- Bash arrays are sparse; you can skip indices.
- Use ${array[@]} to print all elements.
Array Operations
Common operations on Bash indexed arrays.
Accessing array elements
Demonstrates accessing first, last, all elements, count, slice, and keys of an array.
#!/bin/bash
Fruits=('Apple' 'Banana' 'Orange' 'Mango' 'Kiwi')echo "First: ${Fruits[0]}"echo "Last: ${Fruits[-1]}"echo "All: ${Fruits[@]}"echo "Count: ${#Fruits[@]}"echo "Slice: ${Fruits[@]:1:3}"echo "Keys: ${!Fruits[@]}"bash ./array_ops.shFirst: AppleLast: KiwiAll: Apple Banana Orange Mango KiwiCount: 5Slice: Banana Orange MangoKeys: 0 1 2 3 4- Negative indices like ${Fruits[-1]} require Bash 4.2+.
- ${Fruits[@]:offset:length} extracts a slice of the array.
- ${!Fruits[@]} returns all valid indices.
Push, remove, and concatenate
Shows how to append, remove by pattern, unset by index, and merge arrays.
#!/bin/bash
Fruits=('Apple' 'Banana' 'Orange')
# PushFruits+=('Mango')echo "After push: ${Fruits[@]}"
# Remove by regexFruits=("${Fruits[@]/Ban*/}")echo "After remove: ${Fruits[@]}"
# Unset by indexunset 'Fruits[2]'echo "After unset: ${Fruits[@]}"
# ConcatenateVeggies=('Carrot' 'Pea')Combined=("${Fruits[@]}" "${Veggies[@]}")echo "Combined: ${Combined[@]}"bash ./array_modify.shAfter push: Apple Banana Orange MangoAfter remove: Apple Orange MangoAfter unset: Apple MangoCombined: Apple Mango Carrot Pea- The += operator appends elements to an existing array.
- Pattern removal may leave empty elements in the array.
- unset removes the element but does not reindex the array.
Array Iteration
Iterating over array elements in Bash.
Iterating over array elements
Loops over each element in the array using "${array[@]}".
#!/bin/bash
Fruits=('Apple' 'Banana' 'Orange')
for fruit in "${Fruits[@]}"; do echo "Fruit: $fruit"donebash ./iterate.shFruit: AppleFruit: BananaFruit: Orange- Always quote "${array[@]}" to handle elements with spaces.
- Use "${!array[@]}" to iterate over indices instead.
Dictionaries
Working with associative arrays (key-value pairs) in Bash.
Associative Arrays
Declaring and using associative arrays in Bash 4+.
Declaring and using an associative array
Creates an associative array of animal sounds and demonstrates access patterns.
#!/bin/bash
declare -A soundssounds[dog]="bark"sounds[cat]="meow"sounds[bird]="tweet"
echo "Dog: ${sounds[dog]}"echo "All values: ${sounds[@]}"echo "All keys: ${!sounds[@]}"echo "Count: ${#sounds[@]}"bash ./assoc.shDog: barkAll values: tweet bark meowAll keys: bird dog catCount: 3- declare -A is required for associative arrays.
- The order of keys is not guaranteed.
- Requires Bash 4.0 or newer.
Deleting a key
Removes a key from the associative array using unset.
#!/bin/bash
declare -A soundssounds[dog]="bark"sounds[cat]="meow"unset 'sounds[dog]'echo "Remaining keys: ${!sounds[@]}"echo "Remaining values: ${sounds[@]}"bash ./assoc_delete.shRemaining keys: catRemaining values: meow- Quote the key in unset to prevent glob expansion.
Dictionary Iteration
Iterating over keys and values in associative arrays.
Iterating over values and keys
Iterates over all values with ${sounds[@]} and all keys with ${!sounds[@]}.
#!/bin/bash
declare -A soundssounds[dog]="bark"sounds[cat]="meow"sounds[bird]="tweet"
echo "=== Values ==="for val in "${sounds[@]}"; do echo "$val"done
echo "=== Keys ==="for key in "${!sounds[@]}"; do echo "$key: ${sounds[$key]}"donebash ./dict_iter.sh=== Values ===tweetbarkmeow=== Keys ===bird: tweetdog: barkcat: meow- The iteration order is not guaranteed for associative arrays.
- Use "${!array[@]}" to get keys and access values via ${array[$key]}.
Parameter Expansions
Bash string manipulation and parameter expansion techniques.
String Substitution
Replacing and removing substrings using parameter expansion.
Replacing and removing substrings
Demonstrates single and global replacement, and prefix and suffix removal with parameter expansion.
#!/bin/bash
name="John Smith"echo "${name/J/j}"echo "${name//o/0}"
file="hello.tar.gz"echo "${file%.*}"echo "${file%%.*}"echo "${file#*.}"echo "${file##*.}"bash ./substitution.shjohn SmithJ0hn Smithhello.tarhellotar.gzgz- ${var/pattern/replacement} replaces the first match.
- ${var//pattern/replacement} replaces all matches.
- ${var%pattern} removes the shortest suffix match.
- ${var%%pattern} removes the longest suffix match.
- ${var#pattern} removes the shortest prefix match.
- ${var##pattern} removes the longest prefix match.
String Slicing
Extracting substrings and getting string length.
Substrings and length
Extracts substrings by offset and length, and gets string length.
#!/bin/bash
name="Hello World"
echo "${name:0:5}"echo "${name:6}"echo "${name:(-5)}"echo "${#name}"bash ./slice.shHelloWorldWorld11- ${name:offset:length} extracts a substring.
- ${name:(-N)} extracts from the end (parentheses required).
- ${#name} returns the string length.
Default Values
Setting default values for unset or empty variables.
Default value expansions
Shows the four default value operators: use default, assign default, use alternative, and error if unset.
#!/bin/bash
unset fooecho "${foo:-default_val}"echo "foo is: '${foo}'"
echo "${foo:=assigned_val}"echo "foo is: '${foo}'"
echo "${foo:+replacement}"
unset barecho "${bar:?'bar is required'}" 2>&1 || truebash ./defaults.shdefault_valfoo is: ''assigned_valfoo is: 'assigned_val'replacementbash: bar: bar is required- ${foo:-val} uses val if foo is unset or empty, without assigning.
- ${foo:=val} assigns val to foo if unset or empty.
- ${foo:+val} uses val only if foo IS set and non-empty.
- ${foo:?message} prints error and exits if foo is unset or empty.
Case Manipulation
Changing string case using parameter expansion.
Case conversion
Converts strings to lowercase, uppercase, and toggles the first character.
#!/bin/bash
str="Hello World"
echo "${str,,}"echo "${str^^}"echo "${str,}"echo "${str^}"bash ./case_manip.shhello worldHELLO WORLDhello WorldHello World- ${str,,} converts the entire string to lowercase.
- ${str^^} converts the entire string to uppercase.
- ${str,} lowercases only the first character.
- ${str^} uppercases only the first character.
- Requires Bash 4.0 or newer.
I/O and Redirection
Input/output redirection, heredocs, and process substitution in Bash.
Redirection
Redirecting standard input, output, and error streams.
Output and error redirection
Demonstrates common redirection operators for stdout, stderr, and stdin.
#!/bin/bash
# Redirect stdout to fileecho "hello" > output.txt
# Append stdout to fileecho "world" >> output.txt
# Redirect stderr to filels /nonexistent 2> error.log
# Redirect stderr to stdoutls /nonexistent 2>&1
# Redirect both stdout and stderr to filels /nonexistent &> all.log
# Discard outputls /nonexistent 2>/dev/null
# Read stdin from filecat < output.txtbash ./redirect.shhelloworld- > overwrites the file; >> appends to it.
- 2> redirects stderr only.
- 2>&1 sends stderr to the same destination as stdout.
- &> redirects both stdout and stderr.
- < reads stdin from a file.
Heredoc and Herestring
Using heredocs and herestrings for multi-line and inline input.
Heredoc
Passes multi-line text to cat using a heredoc delimiter.
#!/bin/bash
cat <<ENDHelloWorldENDbash ./heredoc.shHelloWorld- The delimiter (END) must appear alone on its own line.
- Variables inside heredocs are expanded by default.
- Use <<'END' (quoted) to prevent variable expansion.
Herestring
Feeds a string directly to a command using the <<< operator.
#!/bin/bash
read -r first second <<< "Hello World"echo "First: $first"echo "Second: $second"bash ./herestring.shFirst: HelloSecond: World- Herestrings pass a single string as stdin.
- Useful as an alternative to echo "string" | command.
Reading Input
Reading user input from the terminal.
Reading user input
Reads a full line and a single character from user input.
#!/bin/bash
read -r -p "Enter your name: " nameecho "Hello, $name!"
read -r -n 1 -p "Continue? (y/n) " answerecho ""echo "You chose: $answer"bash ./read_input.shAliceyEnter your name: Hello, Alice!Continue? (y/n) You chose: y- -r prevents backslash interpretation.
- -p sets a prompt string.
- -n 1 reads only one character.
Process Substitution
Using process substitution to treat command output as files.
Comparing two command outputs
Uses process substitution to compare directory listings without temporary files.
#!/bin/bash
diff <(ls /usr/bin) <(ls /usr/local/bin)bash ./procsub.sh< file_only_in_bin> file_only_in_local_bin- <(command) provides command output as a file descriptor.
- >(command) sends input to a command as a file descriptor.
- This avoids the need for temporary files.
Advanced Bash
Advanced Bash techniques for robust scripting.
Strict Mode
Using strict mode options for safer Bash scripts.
Enabling strict mode
Enables strict mode that exits on errors, unset variables, and pipe failures.
#!/bin/bash
set -euo pipefailIFS=$'\n\t'
echo "Running in strict mode"echo "Unset var: $UNSET_VAR"bash ./strict.shRunning in strict modebash: UNSET_VAR: unbound variable- -e exits on any command failure.
- -u treats unset variables as errors.
- -o pipefail returns the exit code of the first failing command in a pipe.
- IFS=$'\n\t' prevents word splitting on spaces.
Trap and Error Handling
Using trap for error handling and cleanup.
Trap on error
Traps ERR signal and prints the line number where the error occurred.
#!/bin/bash
trap 'echo "Error at line $LINENO"' ERR
echo "Before error"falseecho "This will not run"bash ./trap_err.shBefore errorError at line 6- ERR trap fires whenever a command returns a non-zero exit status.
- $LINENO contains the current line number.
Trap for cleanup on exit
Uses EXIT trap to ensure temporary files are cleaned up when the script exits.
#!/bin/bash
tmpfile=$(mktemp)cleanup() { rm -f "$tmpfile" echo "Cleaned up $tmpfile"}trap cleanup EXIT
echo "Working with $tmpfile"echo "data" > "$tmpfile"bash ./trap_exit.shWorking with /tmp/tmp.XXXXXXXXXXCleaned up /tmp/tmp.XXXXXXXXXX- EXIT trap runs when the script finishes, regardless of how it exits.
- Use trap for cleanup of temporary files, lock files, etc.
Case / Switch
Pattern matching with case/esac statements.
Case statement with patterns
Matches user input against patterns and executes the corresponding block.
#!/bin/bash
read -r -p "Enter a fruit: " fruitcase "$fruit" in "apple") echo "Apple is red" ;; "banana"|"plantain") echo "Banana is yellow" ;; "orange") echo "Orange is orange" ;; *) echo "Unknown fruit: $fruit" ;;esacbash ./case_switch.shbananaEnter a fruit: Banana is yellow- Use | to match multiple patterns in one branch.
- *) acts as the default/fallback case.
- Each branch ends with ;; to stop matching.
Printf Formatting
Formatted output with printf.
Printf examples
Demonstrates printf with string, integer, float, and padding format specifiers.
#!/bin/bash
printf "Hello %s\n" "World"printf "Number: %d\n" 42printf "Float: %.2f\n" 3.14159printf "Padded: %10s|\n" "right"printf "Padded: %-10s|\n" "left"printf '%s\n' "line1" "line2" "line3"bash ./printf.shHello WorldNumber: 42Float: 3.14Padded: right|Padded: left |line1line2line3- %s for strings, %d for integers, %f for floats.
- printf does not add a newline automatically; use \n.
- printf reuses the format string for extra arguments.
Special Variables
Built-in special variables in Bash.
Common special variables
Displays the most commonly used Bash special variables.
#!/bin/bash
echo "Exit status of last command: $?"echo "PID of current script: $$"echo "Script name: $0"echo "Last argument of previous command: $_"echo "Random number: $RANDOM"echo "Current line number: $LINENO"
sleep 0.1 &echo "PID of last background process: $!"wait
true | false | trueecho "PIPESTATUS: ${PIPESTATUS[@]}"bash ./special.shExit status of last command: 0PID of current script: 12345Script name: ./special.shLast argument of previous command: ./special.shRandom number: 28317Current line number: 7PID of last background process: 12346PIPESTATUS: 0 1 0- $? is the exit status of the last command (0 = success).
- $$ is the PID of the current shell.
- $! is the PID of the last background process.
- ${PIPESTATUS[@]} gives exit codes of all commands in the last pipeline.
- $RANDOM generates a random integer between 0 and 32767.
Brace Expansion
Generating arbitrary strings with brace expansion.
Brace expansion patterns
Shows comma-separated, range, stepped, and combined brace expansions.
#!/bin/bash
echo {A,B}.jsecho {1..5}echo {1..10..2}echo {a..z..3}echo pre{fix,lude,pare}echo {1..3}{a..c}bash ./brace.shA.js B.js1 2 3 4 51 3 5 7 9a d g j m p s v yprefix prelude prepare1a 1b 1c 2a 2b 2c 3a 3b 3c- {A,B} expands to each comma-separated item.
- {1..5} generates a numeric sequence.
- {1..10..2} generates a sequence with a step.
- Brace expansion is performed before other expansions.
History Expansion
Reusing and modifying previous commands with history expansion.
History expansion operators
Demonstrates history expansion operators for recalling and modifying commands.
# Re-run the last command!!
# Last argument of the previous commandecho !$
# All arguments of the previous commandecho !*
# Run command number 42 from history!42
# Replace text in the last command and re-run!!:s/from/to/- !! repeats the entire last command.
- !$ is the last argument of the previous command.
- !* is all arguments of the previous command.
- !n runs command number n from history.
- !!:s/from/to/ substitutes text in the last command.
- History expansion is mainly useful in interactive shells.