Skip to content

Linux Command Line

This guide gives you a solid foundation for using the Linux command line with confidence.

I recommend following along in your own terminal as you progress. The best way to learn the command line is by using it. Experiment with each command, try variations, and make it part of your workflow.

The examples in this guide use a Linux environment and Bash. Many of the commands also work on macOS and other Unix-like systems, although some options and behaviors may differ.

This guide is designed for engineers, researchers, and developers who have a basic familiarity with Linux and core computing concepts. No prior experience with Bash scripting is required.

The Linux command line is often associated with the terminal, shell, and prompt. While these terms are sometimes used interchangeably, they refer to different parts of the system.

The terminal is essentially a text-based interface used to interact with the computer. Its origins go way back to the early 1950s with MIT’s Whirlwind I computer, the first to use a typewriter for input and a printer for output.

By the mid-1960s, more advanced display-based terminals like the IBM 2260 began to emerge. During this era, computers were massive machines known as mainframes, and users could connect to them remotely via individual terminals.

The IBM 2260 terminal
The IBM 2260 display-based terminal. Credit: Norsk Teknisk Museum.

These early terminals were quite simple: just a keyboard and a screen. They didn’t have the processing power to run programs on their own. Their sole purpose was to send whatever you typed to the central mainframe and then display the data they received back on the screen.

Today, the Linux command line provides a powerful interface for interacting with the computer. Instead of clicking on icons, you type commands into an application called the terminal. Working behind the scenes, a program known as the shell interprets your commands, understands your intent, and instructs the computer to perform the desired actions.

macOS Terminal

If you’re using Linux or macOS, the terminal is already available with common Linux commands. On Windows, install the Windows Subsystem for Linux (WSL). Setup instructions are available at learn.microsoft.com/windows/wsl.

When you launch the Terminal, you should see a shell prompt similar to this:

Terminal window
borges@linux:~ $

Let’s begin with the date command, which displays the current date and time:

Terminal window
borges@linux:~ $ date
Tue Jul 28 08:25:32 CEST 2025

A related command is cal, which displays a calendar for the current month:

Terminal window
borges@linux:~ $ cal
July 2025
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

These are the most important commands to help you navigate the file system.

Print the current working directory:

Terminal window
pwd

List the contents of the current directory:

Terminal window
ls

List the contents of a specific directory:

Terminal window
ls /home

The -l option displays the contents in long listing format with additional information:

Terminal window
ls -l /home
total 4
drwxr-x--- 6 borges borges 4096 Jul 28 10:25 borges

The output shows:

  • d indicates that the entry is a directory
  • rwxr-x--- are the permissions
  • 6 is the number of hard links to the entry
  • borges is the owner
  • The second borges is the group
  • 4096 is the size in bytes
  • Jul 28 10:25 is the last modification date and time

To make the file size easier to read, add the -h option:

Terminal window
ls -lh /home
total 4.0K
drwxr-x--- 6 borges borges 4.0K Jul 28 10:25 borges

This next command uses the -a option to show all files, including hidden ones:

Terminal window
ls -alh /home/borges
total 40K
drwxr-x--- 6 borges borges 4.0K Jul 28 08:30 .
drwxr-xr-x 3 root root 4.0K Jul 28 08:30 ..
-rw-r--r-- 1 borges borges 3.7K Mar 31 2024 .bashrc
-rw-r--r-- 1 borges borges 807 Mar 31 2024 .profile
drwx------ 2 borges borges 4.0K Jul 28 10:25 .ssh
Terminal window
borges@linux:~ $ cd /usr/bin
borges@linux: /usr/bin $

In this example we start in ~, which refers to the home directory, and move to /usr/bin.

From /usr/bin, let’s navigate to its parent directory:

Terminal window
borges@linux: /usr/bin $ cd ..
borges@linux: /usr $

Now, our current working directory is /usr. Let’s return to the home directory:

Terminal window
borges@linux: /usr $ cd ~
borges@linux:~ $

From here, we can go back to the previous working directory:

Terminal window
borges@linux:~ $ cd -
borges@linux: /usr $

This section introduces commands for inspecting files in the file system.

Displays or combines the contents of files:

Terminal window
cat filename

Display the first 10 lines of a file:

Terminal window
head filename

Display the last 10 lines of a file:

Terminal window
tail filename

Count lines, words, and bytes in a file:

Terminal window
wc filename

View file content:

Terminal window
less filename
  1. Display the contents of a text file:

    Terminal window
    cat /etc/passwd
  2. Display the first 5 lines of a file:

    Terminal window
    head -n 5 /etc/passwd
  3. Display the last 2 lines of a file:

    Terminal window
    tail -n 2 /etc/passwd
  4. Count the number of lines, words, and characters in a file:

    Terminal window
    wc /etc/passwd
    32 45 1656 /etc/passwd

    Where:

    • 32: lines
    • 45: words
    • 1656: bytes
  5. Count only the characters in a file:

    Terminal window
    wc --chars /etc/passwd
  6. Open a sample text file:

    Terminal window
    less /etc/services
  7. Practice moving, searching, and quitting:

    Moving: j, k, f, b, d, u

    Searching: /term, n, N

    Jumping: g, G

    Quitting: q

A command can be an executable program, an internal shell command, a shell function or script, or an alias that can be defined by several commands.

Display command details:

Terminal window
type date
date is /bin/date
Terminal window
type type
type is a shell builtin

Display command location:

Terminal window
which bash
/bin/bash

You can copy a specific file or directory using the cp command:

Terminal window
cp source destination
Terminal window
cp /source_dir/myfile /destination_dir/

Copy a file to another directory and rename it

Section titled “Copy a file to another directory and rename it”
Terminal window
cp /source_dir/myfile /destination_dir/new_filename

Copy a directory and its content into another directory

Section titled “Copy a directory and its content into another directory”

You must use the -r option to copy directories.

Terminal window
cp -r /source_dir/mydir /destination_dir/

The command mv is used to move a file or directory from one location to another, or to rename a file or directory within the same location. Unlike cp, moving a file or directory removes it from the source location.

Terminal window
mv source destination
Terminal window
mv old_filename.txt new_filename.txt
Terminal window
mv myfile.txt /destination_dir/
Terminal window
mv /source_dir/mydir /destination_dir/

The command mkdir (make directory) is used to create one or more new directories in the specified location.

Terminal window
mkdir directory_name

Create a single directory in the current location

Section titled “Create a single directory in the current location”
Terminal window
mkdir projects
Terminal window
mkdir scripts docs logs

Use the -p option to create multiple directories in a path.

Terminal window
mkdir -p project/src/main

The command touch is commonly used to create a new empty file if the file does not already exist.

Terminal window
touch filename

The command rm (remove) is used to permanently delete files or directories. Use this command with caution, as deleted files are typically unrecoverable.

Terminal window
rm filename
Terminal window
rm unnecessary_file.txt
Terminal window
rm log_*.txt temp_file.bak

To remove a directory, the -r (recursive) option is required.

Terminal window
rm -r old_project_folder/

Force-remove a directory without prompting

Section titled “Force-remove a directory without prompting”
Terminal window
rm -rf very_old_backup/

In Linux-based systems, links are used to create references to files or directories, allowing a single item to be accessed via multiple names or locations.

We have two distinct kinds of links:

  • Hard link: another name for the same file. If one name is deleted, the other still provides access to the file.
  • Soft link (symbolic link): a shortcut that points to another file or directory. If the target is deleted, the link breaks.

Linux links

Terminal window
ln target link_name
Terminal window
ln -s target link_name
  1. Create a playground directory:

    Terminal window
    mkdir /tmp/playground
  2. Change to the playground directory:

    Terminal window
    cd /tmp/playground
  3. Create multiple directories following the example:

    • Directorydir1/
    • Directorydir2/
      • Directorydir3/
    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
    • Directoryfiles/
    Terminal window
    mkdir dir1 dir2 dir4 files
    Terminal window
    mkdir dir2/dir3 dir4/dir5
    Terminal window
    mkdir dir4/dir5/dir6
  4. Create files inside dir3:

    • Directorydir2/
      • Directorydir3/
        • file_1.txt
        • file_2.txt
        • file_3.txt
    Terminal window
    touch dir2/dir3/file_1.txt
    Terminal window
    touch dir2/dir3/file_2.txt
    Terminal window
    touch dir2/dir3/file_3.txt
  5. Recursively list all directories and files:

    Terminal window
    ls -R
    • Directorydir1/
    • Directorydir2/
      • Directorydir3/
        • file_1.txt
        • file_2.txt
        • file_3.txt
    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
    • Directoryfiles/
  6. Copy /etc/passwd into dir6/file_4.txt:

    • /etc/passwd
    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
          • file_4.txt

    Using a relative path, run:

    Terminal window
    cp /etc/passwd dir4/dir5/dir6/file_4.txt
  7. Create a symbolic link to file_4.txt:

    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
          • file_4.txt
    • soft_link.txt -> dir4/dir5/dir6/file_4.txt
    Terminal window
    ln -s dir4/dir5/dir6/file_4.txt soft_link.txt
  8. List files in the current directory with detailed info:

    Terminal window
    ls -l
    • Directorydir1/
    • Directorydir2/
    • Directorydir4/
    • Directoryfiles/
    • soft_link.txt -> dir4/dir5/dir6/file_4.txt
  9. Create a hard link to file_4.txt:

    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
          • file_4.txt
    • hard_link.txt
    Terminal window
    ln dir4/dir5/dir6/file_4.txt hard_link.txt
  10. Remove the file_4.txt file:

    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
          • file_4.txt
    Terminal window
    rm dir4/dir5/dir6/file_4.txt
  11. List files in the current directory with detailed info:

    Terminal window
    ls -l
    • Directorydir1/
    • Directorydir2/
    • Directorydir4/
    • Directoryfiles/
    • hard_link.txt
    • soft_link.txt -> dir4/dir5/dir6/file_4.txt

    The symbolic link soft_link.txt is still present, but it is now broken. The hard link hard_link.txt, however, still works and provides access to the file.

  12. Attempt to display the content of the soft_link.txt file:

    Terminal window
    cat soft_link.txt
    cat: soft_link.txt: No such file or directory

    The target file cannot be accessed through the symbolic link because the link is broken.

  13. Display the first 10 lines of hard_link.txt file:

    Terminal window
    head hard_link.txt
  14. Rename the hard link hard_link.txt to output.txt:

    Terminal window
    mv hard_link.txt output.txt
  15. Remove the soft_link.txt file:

    Terminal window
    rm soft_link.txt
  16. Recursively list all directories and files:

    Terminal window
    ls -R
    • Directorydir1/
    • Directorydir2/
      • Directorydir3/
        • file_1.txt
        • file_2.txt
        • file_3.txt
    • Directorydir4/
      • Directorydir5/
        • Directorydir6/
    • Directoryfiles/
    • output.txt

This section covers commands for controlling the standard input, output, and error of processes, making it easier to manage and manipulate data.

In Linux, every process automatically starts with three data streams:

  1. Standard input (stdin): the channel through which a program receives data, usually from the keyboard or a file.
  2. Standard output (stdout): where a program sends its results, usually shown on the terminal.
  3. Standard error (stderr): used to display error messages.

Linux process IO

To redirect the standard output of a process to a file instead of displaying it on the screen, use the redirection operator > followed by the file name.

For example, we can redirect the output of the cal -m July command to a file instead of displaying it on the screen:

Terminal window
cal -m July > /tmp/calendar.txt

Then, we can display the file content:

Terminal window
cat /tmp/calendar.txt
July 2025
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Now, let’s see what happens if we type the command incorrectly:

Terminal window
cal -m month > /tmp/calendar.txt
cal: month is neither a month number (1..12) nor a name

We get an error message because the command expects either a valid month name or a number between 1 and 12, not the term month.

Now, let’s display the file content:

Terminal window
cat /tmp/calendar.txt

The file is empty because the command cal -m month produced an error and didn’t generate the calendar as expected.

As you may notice, the redirection operator > overwrites the file, discarding its previous data. If you want to preserve the existing data, you can use the append operator >>, which adds new data to the end of the file.

  1. Overwriting the file with the July calendar:

    Terminal window
    cal -m July > /tmp/calendar.txt
  2. Appending the file with the August calendar:

    Terminal window
    cal -m August >> /tmp/calendar.txt
  3. Displaying the contents of the file:

    Terminal window
    cat /tmp/calendar.txt
    July 2025
    Su Mo Tu We Th Fr Sa
    1 2 3 4 5
    6 7 8 9 10 11 12
    13 14 15 16 17 18 19
    20 21 22 23 24 25 26
    27 28 29 30 31
    August 2025
    Su Mo Tu We Th Fr Sa
    1 2
    3 4 5 6 7 8 9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
    31

Redirecting standard error is easier to understand once you know that the shell treats standard input, output, and error as separate file descriptors:

  • File descriptor 0: Standard input (stdin)
  • File descriptor 1: Standard output (stdout)
  • File descriptor 2: Standard error (stderr)

This means that a command can produce both normal output and error messages, and the shell can redirect them independently.

For example, ls produces an error for the nonexistent myfile and normal output for /usr:

Terminal window
ls myfile /usr
ls: cannot access 'myfile': No such file or directory
/usr:
bin games include lib libexec local sbin share src

Redirect the output to a file and the error to the terminal

Section titled “Redirect the output to a file and the error to the terminal”

The > operator redirects standard output to a file. It does not affect standard error, so error messages are still displayed in the terminal:

Terminal window
ls myfile /usr > /tmp/output.txt
ls: cannot access 'myfile': No such file or directory

The normal output from /usr is now stored in /tmp/output.txt, while the error message remains visible in the terminal.

Redirect the output to the terminal and the error to a file

Section titled “Redirect the output to the terminal and the error to a file”

To redirect standard error, use 2> instead of >. The 2 refers to file descriptor 2, which represents standard error.

In this example, the normal output is still displayed in the terminal, while the error message is written to /tmp/output.txt:

Terminal window
ls myfile /usr 2> /tmp/output.txt
/usr:
bin games include lib libexec local sbin share src

Redirect both the output and the error to a file

Section titled “Redirect both the output and the error to a file”

In Bash, you can redirect both standard output and standard error to the same file using &>:

Terminal window
ls myfile /usr &> /tmp/output.txt

Now both the normal output and the error message are written to /tmp/output.txt.

There is also a traditional way to achieve the same result using file descriptors:

Terminal window
ls myfile /usr > /tmp/output.txt 2>&1

Here, we perform two redirections. First, > redirects standard output to /tmp/output.txt. Then, 2>&1 redirects standard error (file descriptor 2) to the same destination as standard output (file descriptor 1).

The order matters. The shell processes these redirections from left to right, so 2>&1 redirects standard error to wherever standard output is currently pointing.

You can discard standard error by redirecting it to /dev/null:

Terminal window
ls myfile /usr 2> /dev/null
/usr:
bin games include lib libexec local sbin share src

Here, 2> redirects standard error (file descriptor 2) to /dev/null. The error message is discarded, while the normal output is still displayed in the terminal.

Standard input allows a command to receive data from a source such as the keyboard or a file. Use the < operator to redirect standard input from a file.

Let’s create a simple text file:

Terminal window
printf "Zucchini\nApple\nCherry\n" > /tmp/items.txt

Now, redirect standard input from the file:

Terminal window
sort < /tmp/items.txt
Apple
Cherry
Zucchini

Instead of reading input from the keyboard, sort reads the contents of /tmp/items.txt through standard input.

A pipeline allows you to use the pipe operator | to send the standard output of one command as the standard input to another command.

Let’s display some data and pass it through a pipeline to sort the output:

Terminal window
printf "Zucchini\nApple\nCherry\n" | sort
Apple
Cherry
Zucchini

Now, let’s sort some data and use a pipeline to remove duplicates:

Terminal window
printf "Red\nBlue\nYellow\nBlue\nYellow\nRed" | sort | uniq
Blue
Red
Yellow

Here’s an example of filtering by the specific term python:

Terminal window
ls /usr/bin | grep python
pybabel-python3
python3
python3.14

Explore the docs for each command. We have only scratched the surface!

With more practice you will see how redirection is used for solving real problems, and how standard input, output, and error are at the core of nearly every command-line tool.

The find command is a powerful tool for searching files and directories based on their name, type, permissions, date, ownership, size, and more. It can also execute commands on the results, making it very flexible.

Terminal window
find [path] [expression]

Searching for any regular file named bash:

Terminal window
find /usr/ -name "bash"

Searching for files ending with the term bash:

Terminal window
find /usr/ -name "*bash"

Searching for files starting with the term bash:

Terminal window
find /usr/ -name "bash*"

Searching for files containing the term bash:

Terminal window
find /usr/ -name "*bash*"

Searching for files with a .txt extension:

Terminal window
find /usr/ -name "*.txt"

Searching for directories:

Terminal window
find /usr/ -type d

Searching for directories named linux:

Terminal window
find /usr/ -type d -name "linux"

Searching for regular files:

Terminal window
find /usr/ -type f

Searching for .txt files with names starting with bash:

Terminal window
find /usr/ -type f -name "bash*.txt"

Searching for symbolic links:

Terminal window
find /usr/ -type l

Searching for symbolic links named python3:

Terminal window
find /usr/ -type l -name "python3"

Searching for files larger than 10 Megabytes:

Terminal window
find /usr/ -size +10M

Searching for files smaller than 1 Kilobyte:

Terminal window
find /usr/ -size -1k

Searching for files owned by your user:

Terminal window
find ~ -user "$(whoami)"

The -exec option allows you to run a command on each file found. This makes find much more powerful. The syntax is:

Terminal window
find [path] [expression] -exec command {} \;

The {} is replaced by the current file, and the sequence must end with \;.

Examples:

Listing details of all .txt files:

Terminal window
find ~ -name "*.txt" -exec ls -l {} \;

Printing the first line of each .txt file:

Terminal window
find ~ -name "*.txt" -exec head -n 1 {} \;

Removing empty files (safe to try in a test directory):

Terminal window
find ./testdir -type f -empty -exec rm {} \;

The grep command is used to search text inside files using patterns and regular expressions. It is one of the most common tools for quickly finding matching lines in logs, source code, or any other text file.

Terminal window
grep [options] pattern [file...]

Searching for the word admin in a file:

Terminal window
grep "admin" /etc/passwd

Ignoring case (matches admin, Admin, ADMIN, etc.):

Terminal window
grep -i "admin" /etc/passwd

Searching for lines starting with root:

Terminal window
grep "^root" /etc/passwd

Searching for lines ending with bash:

Terminal window
grep "bash$" /etc/passwd

Searching for lines that contain a number:

Terminal window
grep "[0-9]" /etc/passwd

Searching for lines containing cat, bat, or hat:

Terminal window
grep "[cbh]at" /etc/passwd

With -E we can use more advanced patterns.

Searching for either Daemon or Proxy:

Terminal window
grep -E "Daemon|Proxy" /etc/passwd

Searching for words ending with ing:

Terminal window
grep -E "[a-zA-Z]+ing" /etc/passwd

Counting the number of matches for the word false:

Terminal window
grep -c "false" /etc/passwd

Showing only the names of files containing the word main:

Terminal window
grep -rl "main" /path/to/directory

A Bash script is a text file containing commands that are executed in sequence. Scripts are essential for system administration, allowing you to automate tasks, create simple programs, and combine existing commands into efficient, reusable workflows.

  1. Create a script file using nano or your favorite code editor:

    Terminal window
    nano /tmp/script.sh
  2. Copy and paste the content below, and save:

    #!/usr/bin/env bash
    # A simple script
    echo "Hello, world!"

    The first line, known as the shebang, specifies Bash as the interpreter for the script. The second line is a comment. The third line uses the echo command to print the specified string to the standard output.

  3. Make the file executable:

    To run a bash script correctly, you must ensure it has execution permission. For that, we use the chmod command (short for change mode), which is a fundamental Linux command used to control access to files and directories.

    Close the nano editor and set the execution permission to the script:

    Terminal window
    chmod +x /tmp/script.sh
  4. Run the script:

    Terminal window
    bash /tmp/script.sh

Comments help explain the purpose of certain lines. They should only be used to explain less obvious parts of the code.

Terminal window
# This is a comment!
# Comments start with a hash (#)
#
# Something important here! Albert Einstein

Variables are used to store values. No spaces are allowed around the equal sign.

Terminal window
NAME="Alice"
CITY="Paris"
echo "${NAME} lives in ${CITY}"

You can assign multi-line text to a variable using the here-document syntax, which allows you to embed a block of text or commands directly within a script. Below is an example of how you can define a multi-line variable.

Copy and paste this into the terminal:

Terminal window
TEXT="$(cat << EOF
---
The current directory is: ${PWD}
You are logged in as: $(whoami)
---
EOF
)"
echo "${TEXT}"

By default, the shell performs parameter expansion and command substitution inside the here-document. For example, ${PWD} expands to the current directory and $(whoami) is replaced by the current user.

If you need to preserve the literal contents without performing expansions or substitutions, quote the opening delimiter with << 'EOF', so the text is stored or printed exactly as written. Below is an example of how to define a multi-line variable without expansion. Pay attention to the details and compare it with the previous (unquoted) example to observe the difference.

Copy and paste the following into the terminal:

Terminal window
TEXT="$(cat << 'EOF'
---
The current directory is: ${PWD}
You are logged in as: $(whoami)
---
EOF
)"
echo "${TEXT}"

Bash supports indexed arrays, which provide a way to store multiple data elements that can be accessed by their position (index), starting from 0. Check the example below.

Copy and paste this into the terminal:

Terminal window
COLORS=("red" "green" "blue")
echo "0: ${COLORS[0]}"
echo "1: ${COLORS[1]}"
echo "2: ${COLORS[2]}"

The read command waits for the user to enter a value and stores it in a variable. In this example, the input is stored in the NAME variable.

When read runs, the shell pauses until the user types something and presses Enter. The value can then be used by subsequent commands.

Copy and paste the following into the terminal:

Terminal window
echo "Enter your name:"
read NAME
echo
echo "Welcome ${NAME}."

Control flow in Bash scripting is essential for making decisions and performing repetitive tasks. It determines the order in which commands are executed based on conditions.

Mastering control flow allows a script to move beyond simple sequential commands to dynamic and powerful automation.

An if statement is a control structure that executes one or more commands based on the result of a condition.

Here is an example of an if statement:

Terminal window
if [[ "CONDITION" ]]; then
"INSTRUCTIONS"
fi

Now, a more complete example:

Terminal window
NAME="Alice"
if [[ "${NAME}" = "Alice" ]]; then
echo "Welcome, Alice."
else
echo "You are not Alice."
fi

We have several ways to perform tests and conditional checks in Bash. Below are the most commonly used tests:

Terminal window
if [[ -f "myfile.txt" ]]; then
echo "File exists"
else
echo "File not found"
fi
Terminal window
if [[ 1 -lt 2 ]]; then
echo "Are you sure?"
fi

A for loop allows a block of code to be executed repeatedly. For example, we can use it to print all the elements of an array like this:

Terminal window
COLORS=("red" "green" "blue")
for COLOR in "${COLORS[@]}"
do
echo "Color: ${COLOR}"
done

Here’s another way to do it by looping over strings:

Terminal window
for COLOR in "red" "green" "blue"
do
echo "Color: ${COLOR}"
done

You can also loop over a range:

Terminal window
for i in {0..3}
do
echo "Number: ${i}"
done
  1. Create a new script:

    Terminal window
    nano /tmp/calendar.sh
  2. Copy and paste the content below, and save:

    #!/usr/bin/env bash
    echo "Calendar Display Utility"
    echo
    echo "Please enter the month number (1-12):"
    read MONTH
    # Print the calendar for the month
    cal -m "${MONTH}"
  3. Make the file executable:

    Terminal window
    chmod +x /tmp/calendar.sh
  4. Run the script:

    Terminal window
    bash /tmp/calendar.sh

You now have the foundations you need to work comfortably at the Linux command line. You can navigate the file system, inspect and manage files, redirect input and output, connect commands with pipelines, search for files and text, and write simple Bash scripts.

But the command line really starts to click when you use it to solve your own problems. Don’t worry about memorizing every option or command. Keep experimenting, read the documentation, and gradually build up your own toolbox.

There’s a lot more to discover, but you have everything you need to start exploring.