AB
A detailed guide to mastering Bash commands and shell scripting, essential for Unix-like operating systems.
Bash (Bourne Again Shell) is the default command-line interpreter for most Linux distributions and macOS. Understanding Bash commands and shell scripting concepts is essential for anyone working with Unix-like operating systems. This guide covers fundamental commands, operators, and techniques commonly used in shell scripting.
>
, >>
, <
)The shell provides various operators for redirecting input and output:
>
- Redirects output to a file (overwrites existing content)>>
- Appends output to a file<
- Takes input from a file# Create or overwrite a file with content
echo "Hello" > file.txt
# Append content to a file
echo "World" >> file.txt
# This does NOT work as expected:
echo Hello > touch make.txt
This command doesn’t add “Hello” to a file named “make.txt”. Instead, it:
touch
as a literal string, not a commandTo properly create a file and add content:
# Create an empty file
touch make.txt
# Add content to the file
echo "Hello" > make.txt
<<
, <<<
)<<
)The <<
operator (here document) allows you to provide a block of text as input to a command:
cat << EOF
This is a multi-line
text block that will be
passed to the cat command.
EOF
<<<
)The <<<
operator passes a string directly as input to a command:
grep "search_term" <<< "This is a string to search within."
read
The read
command captures user input in shell scripts:
# Store user input in a variable
read variable_name
# Example with prompt
echo "Please enter your name:"
read name
echo "Hello, $name!"
# Combine prompt and input in one command
read -p "Please enter your name: " name
echo "Hello, $name!"
# Read multiple variables from a single input
read first_name last_name
echo "Your first name is $first_name and your last name is $last_name."
# Silent mode (for passwords)
read -s -p "Enter your password: " password
echo "Password saved."
# Read with timeout (5 seconds)
read -t 5 -p "Quick! Enter something: " input
# Read into an array
read -a my_array -p "Enter values separated by spaces: "
echo "First value: ${my_array[0]}"
wc
)The wc
(word count) command counts lines, words, and characters in files or input:
# Count lines, words, and characters in a file
wc filename.txt
# Count only lines (-l)
wc -l filename.txt
# Count only words (-w)
wc -w filename.txt
# Count only characters (-c)
wc -c filename.txt
# Find the length of the longest line (-L)
wc -L filename.txt
# Count files in current directory
ls | wc -l
sed
)sed
is a powerful stream editor for filtering and transforming text:
# Replace "Lewis" with "Max" in a file
sed 's/Lewis/Max/g' sedtest.txt
In this command:
s
specifies substitution/Lewis/Max/
defines the pattern and replacementg
(global) replaces all occurrences in each line# Edit file in-place and create a backup with .ORIGINAL extension
sed -i.ORIGINAL 's/Lewis/Max/g' sedtest.txt
This creates sedtest.txt.ORIGINAL
as a backup of the original file before making changes.
awk
for Text Processingawk
is a powerful programming language for text processing:
# Print the first field (column) of each line
awk '{print $1}' filename.txt
If filename.txt
contains:
apple 10 red
banana 20 yellow
cherry 30 darkred
The output will be:
apple
banana
cherry
$?
)After running a command, $?
contains its exit status:
0
indicates success# Run a command
ls
# Check its exit status
echo $?
# Use exit status in a conditional
cp source.txt destination.txt
if [ $? -eq 0 ]; then
echo "Copy succeeded!"
else
echo "Copy failed!"
fi
-eq
- Equal to-ne
- Not equal to-gt
- Greater than-lt
- Less than-ge
- Greater than or equal to-le
- Less than or equal to# Equality comparison
if [ $number1 -eq $number2 ]; then
echo "The numbers are equal."
else
echo "The numbers are not equal."
fi
# Inequality comparison
if [ $number1 -ne $number2 ]; then
echo "The numbers are not equal."
fi
=
or ==
- Equal to!=
- Not equal to-z
- String is empty-n
- String is not empty# String equality
if [ "$str1" = "$str2" ]; then
echo "Strings are equal."
fi
# Check if string is empty
if [ -z "$str" ]; then
echo "String is empty."
fi
set
CommandThe set
command can modify shell behavior. A common pattern for safer scripts is:
set -euo pipefail
This combination:
-e
- Exit immediately if a command fails-u
- Treat unset variables as errors-o pipefail
- Make a pipeline fail if any command in it failsExample of its effect:
#!/bin/bash
set -euo pipefail
echo "Starting script..."
# This will cause the script to exit immediately if it fails
some_command_that_might_fail
# This line won't be reached if the above command fails
echo "Script continuing..."
# This will cause an error if UNDEFINED_VARIABLE is not set
echo $UNDEFINED_VARIABLE
Convert strings to lowercase or uppercase:
# Convert to lowercase
lowercase_var=${variable,,}
# Convert first parameter to lowercase
lowercase_param=${1,,}
# Convert to uppercase
uppercase_var=${variable^^}
Working with arrays in Bash:
# Define an array
MY_FIRST_LIST=("apple" "banana" "cherry")
# Access all elements
echo "All fruits: ${MY_FIRST_LIST[@]}"
# Access a specific element (zero-indexed)
echo "Second fruit: ${MY_FIRST_LIST[1]}"
# Get array length
echo "Number of fruits: ${#MY_FIRST_LIST[@]}"
# Loop through array
for fruit in "${MY_FIRST_LIST[@]}"; do
echo "Fruit: $fruit"
done
Command substitution allows you to use the output of a command as part of another command:
# Capture command output in a variable using $()
current_date=$(date +%Y-%m-%d)
echo "Today is $current_date"
# Example: Extract system uptime without "up " prefix
up=$(uptime -p | cut -c4-)
echo "System uptime: $up"
PATH
Variable$PATH
is an environment variable that tells the shell where to look for executable files:
# View your current PATH
echo $PATH
# Add a directory to PATH
export PATH=$PATH:/new/directory/path
A typical PATH might look like:
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin
The ~/.bashrc
file contains initialization commands run when starting a new Bash shell:
# Common additions to .bashrc
alias ll='ls -la'
export PATH="$PATH:$HOME/bin"
# Define a function
function greet() {
echo "Hello, $1!"
}
To apply changes without restarting the shell:
source ~/.bashrc
ln
)The ln
command creates links between files:
Hard links point to the same inode (data) as the original file:
# Create a hard link
ln original.txt hard_link.txt
Characteristics of hard links:
Symbolic links point to the path of the target file:
# Create a symbolic link
ln -s original.txt symbolic_link.txt
Characteristics of symlinks:
fzf
)fzf
is an interactive command-line fuzzy finder:
# Basic usage with pipe
find . -type f | fzf
# Search through command history
history | fzf
# Search through git commits
git log --oneline | fzf
Add to your .bashrc
for better integration:
# Add key binding for fzf
export FZF_DEFAULT_COMMAND='find . -type f -not -path "*/\.git/*"'
bind -x '"\C-f": "fzf"'
This guide covered essential Bash commands and shell scripting concepts. By understanding these fundamentals, you’ll be better equipped to navigate Unix-like systems and create efficient shell scripts. As you continue to work with the command line, you’ll discover more powerful ways to combine these tools to solve complex problems.