Bash cheatsheet

Published May 25, 2025, 5:25 p.m. by james

Bash Cheatsheet

File System Navigation

pwd # Print Working Directory (show current path)
ls # List files and directories
ls -l # List in long format (permissions, size, date)
ls -a # List all files, including hidden (starting with .)
cd <directory> # Change directory
cd .. # Go to parent directory
cd ~ # Go to home directory
cd - # Go to previous directory

File Operations

touch <filename> # Create an empty file or update timestamp
cat <filename> # Display file content
less <filename> # View file content page by page (q to quit)
head <filename> # Display first 10 lines of a file
tail <filename> # Display last 10 lines of a file
tail -f <filename> # Follow file content as it grows (useful for logs)
cp <source> <destination> # Copy file or directory
cp -r <source_dir> <destination_dir> # Copy directory recursively
mv <source> <destination> # Move or rename file/directory
rm <filename> # Remove file
rm -r <directory> # Remove directory recursively
rm -rf <directory> # Force remove directory recursively (use with caution!)

Directory Operations

mkdir <directory_name> # Create directory
mkdir -p <parent_dir/new_dir> # Create parent directories if they don't exist
rmdir <directory_name> # Remove empty directory

Permissions

chmod <permissions> <filename/dirname> # Change file/directory permissions
# Example: chmod 755 script.sh (rwx for owner, r-x for group/others)
# Example: chmod +x script.sh (make script executable)
chown <user>:<group> <filename/dirname> # Change file/directory ownership

Searching

find <directory> -name "filename_pattern" # Find files by name
# Example: find . -name "*.txt" (find all .txt files in current dir and subdirs)
grep "pattern" <filename> # Search for pattern in file
grep -r "pattern" <directory> # Search recursively for pattern in directory

Pipes and Redirection

<command1> | <command2> # Pipe: output of command1 becomes input of command2
<command> > <file> # Redirect standard output to file (overwrite)
<command> >> <file> # Redirect standard output to file (append)
<command> < <file> # Redirect standard input from file
<command> 2> <error_file> # Redirect standard error to file
<command> &> <file> # Redirect both standard output and standard error to file

Process Management

ps aux # List all running processes
top # Display dynamic real-time view of running processes (q to quit)
kill <pid> # Terminate process by Process ID
killall <process_name> # Terminate all processes with that name
<command> & # Run command in background
jobs # List background jobs
fg %<job_number> # Bring background job to foreground
bg %<job_number> # Resume stopped background job

Variables and Basic Scripting

MY_VAR="Hello World" # Assign variable (no spaces around =)
echo $MY_VAR # Print variable value
echo "User is: $USER, Home is: $HOME"

read USER_INPUT # Read input from user
echo "You entered: $USER_INPUT"

# Basic if statement
if [ $MY_VAR == "Hello World" ]; then
  echo "Condition is true"
fi

Archives and Compression

tar -cvf archive.tar <file1> <file2> <dir1> # Create a .tar archive
tar -xvf archive.tar # Extract a .tar archive
tar -czvf archive.tar.gz <files/dirs> # Create a gzipped .tar archive
tar -xzvf archive.tar.gz # Extract a gzipped .tar archive
gzip <filename> # Compress file (creates filename.gz)
gunzip filename.gz # Decompress file

Network Utilities

ping <hostname_or_ip> # Check network connectivity
curl <URL> # Transfer data from or to a server (e.g., download a file)
wget <URL> # Download files from the web
ssh user@hostname # Connect to a remote server via SSH
scp user@hostname:/path/to/remote/file /path/to/local/destination # Secure copy file

Bash One-Liner: Count Lines in C/H Files

Command:

zsh:

c=0; for f in `ls *.(h|c)`; do lines=`cat $f | wc -l`; c=$((c+lines)); done; echo $c

Bash:

shopt -s extglob
c=0; for f in `ls *.@(h|c)`; do lines=`cat $f | wc -l`; c=$((c+lines)); done; echo $c

In-Depth Explanation:

1. Incrementing Variables in Bash: The $((...)) Construct

The command uses c=$((c+lines)) to accumulate the total line count. This is a key way Bash handles integer arithmetic through a feature called **arithmetic expansion**.

  • Syntax: $((expression))
  • Functionality: The shell evaluates the expression within the double parentheses as an arithmetic expression. The result of this evaluation then replaces the entire $((...)) construct.
  • Variable Dereferencing: Inside $((...)), variables like c and lines can be referred to by their names directly (e.g., c instead of $c). The shell automatically dereferences them to their numerical values. Using $c (e.g., $(($c+$lines))) also often works but is not strictly necessary within this construct.
  • Operators: Standard C-style integer arithmetic operators are supported, including + (addition), - (subtraction), * (multiplication), / (integer division), % (modulo), bitwise operators, and more.
  • Assignment: In the command c=$((c+lines)), the result of c+lines is calculated, and this new value is then assigned back to the variable c.
  • Advantages: This POSIX-standard method is generally preferred for arithmetic in scripts over older external commands like expr because it's built into the shell, leading to better performance and more natural syntax.

Other common ways to perform arithmetic and increment variables in Bash include:

  • Arithmetic Context ((...)): This is often used for performing arithmetic and assignments directly without needing the $ for substitution if you're just performing the operation (e.g., for side effects).
    • ((c = c + lines))
    • ((c += lines)) (compound assignment)
    • ((c++)) (increment by one, C-style)
  • let Builtin: The let command also evaluates arithmetic expressions.
    • let "c = c + lines"
    • let "c+=lines"
    • let c++
    Note that arguments to let containing spaces must be quoted.

2. Understanding the File Pattern: *.(h|c) (Extended Globbing)

The pattern *.(h|c) is used within the command substitution `ls *.(h|c)` to select files. While it might share conceptual similarities with regular expressions (regex) in its goal of pattern matching, in the context of Bash, this specific syntax is a **shell glob pattern**, and more precisely, an **extended glob pattern**.

  • Standard Globs vs. Extended Globs:
    • Standard globs include wildcards like * (matches any string of characters), ? (matches any single character), and [...] (matches any one of the enclosed characters).
    • Bash's extended globbing provides more powerful pattern matching capabilities, similar to some regex features, but with its own syntax.
  • Deconstructing *.(h|c):
    • *: The asterisk is a standard glob wildcard that matches any sequence of characters (including an empty sequence) at the beginning of the filename.
    • .: This matches a literal dot character in the filename, separating the base name from the extension.
    • (...): When extended globbing is active, parentheses are used to group patterns.
    • h|c: Inside this extended glob group, the pipe symbol | acts as an **OR** operator. It means "match the pattern to the left (h) OR match the pattern to the right (c)".
    So, the entire pattern *.(h|c) is designed to match any filename that ends with a literal .h OR a literal .c.
  • Prerequisite: shopt -s extglob: For Bash to interpret *.(h|c) as an extended glob pattern (especially the @(pattern-list), !(pattern-list), ?(pattern-list), *(pattern-list), and +(pattern-list) constructs, where .(h|c) is a form similar to @(h|c) when used as part of a filename pattern), the extglob shell option **must be enabled**. You can enable it by running the command: shopt -s extglob. If extglob is disabled, the shell will likely treat (, |, and ) as literal characters when performing filename expansion, or ls might try to find files with these characters in their names, which would not yield the desired list of .h and .c files.
  • Alternative (without extglob): If extglob is not enabled or desired, a more traditional way to list both types of files for ls would be to specify them separately: ls *.h *.c.

Share this post

Similar posts

Git Cheatsheet

Remove All Signatures from a PDF

comment

There are no comments yet.

Add a new comment