linux

Bash: A Complete Guide to Linux, Commands, and Scripting

Bash: A Complete Guide to Linux, Commands, and Scripting

What is Bash and how does it work? Learn Bash commands, variables, pipes, permissions, and scripting with a practical, groundbreaking guide designed for Linux and cybersecurity.

  • Posted on 2026-09-14
  • Reading time: 7 min

Bash: A Complete Guide to Linux Commands and Scripting #

Bash is the shell that interprets and executes commands typed in the terminal on Linux and Unix-like systems. It allows you to navigate the filesystem, manage files and processes, use variables, chain commands, and automate tasks through scripts. It is a core skill for system administration, DevOps, and IT security.

This guide takes you from zero to solid: syntax, scripting, error handling, and why ethical hacking can't do without it.

In this guide

  1. Bash, Shell, and Terminal: The Difference
  2. Bash vs sh, Zsh, Fish
  3. The prompt
  4. base command
  5. Variables
  6. quoting
  7. Redirection, pipes and stdin/stdout/stderr
  8. Control Operators: &&, ||, ;
  9. File permissions
  10. Conditionals
  11. cycles
  12. Functions
  13. Write and run a script
  14. Exit code and error handling
  15. trap
  16. Best practices for Bash scripts
  17. Bash and cybersecurity
  18. FAQ
  19. How to continue studying

Bash, Shell, and Terminal: The Difference #

There are three distinct levels, and confusing them is the most common mistake for beginners.

text
Tu
 ↓
Terminale (interfaccia)
 ↓
Bash (shell/interprete)
 ↓
Kernel Linux
 ↓
Hardware
  • terminal: the window where you type. It's just the graphical interface (terminal emulator).
  • Shell: the program that interprets the commands you type. Bash is one shell among many.
  • Bash: stands for Bourne Again SHell. It acts as an intermediary between you and the operating system: you write text, it interprets it and executes it by calling the kernel.

Bash vs sh, Zsh, Fish #

Bash is not synonymous with Linux, and it is one of the available shells, not the only one.

ShellMain feature
shHistoric Unix shell, the basis of the POSIX standard
BashWide compatibility, widespread deployment and mature scripting
zshAdvanced interactivity and customization (default on modern macOS)
FishModern syntax oriented towards ease of use

Bash remains one of the most popular shells in the Linux ecosystem and has long been the default choice in many distributions, but which shell is active by default depends on the distribution and system configuration — it should not be taken for granted.

The prompt: how to read it #

When you open a terminal you see something like:

bash
utente@hackita:~$

It is read: utente@nomehost:cartella-corrente$. The $ final indicates a normal user. If you see # in place of $, you are root, the administrator with full power over the system.

base command #

A Bash command has this structure:

bash
comando [opzioni] [argomenti]

Example:

bash
ls -la /home
  • ls is the command (list files and folders)
  • -la these are the options (show all, long format)
  • /home it's the topic (where to look)

Commands you'll use every day:

bash
pwd              # mostra la cartella in cui ti trovi
cd cartella      # entra in una cartella
ls               # elenca file e cartelle
cat file.txt     # mostra il contenuto di un file
mkdir nuova      # crea una cartella
rm file.txt      # elimina un file
cp a.txt b.txt   # copia
mv a.txt b.txt   # sposta/rinomina

Bash doesn't teach you commands; it interprets them. Once you understand the logic of pipes and composition, sequences like this become second nature:

bash
grep "error" logfile.txt | sort | uniq -c
find /var/log -type f -name "*.log"

The Unix mental model is always the same: lots of little tools, combined with |, to obtain a complex result. For a complete list of the most used commands, see top 100 Linux commands.

Variables #

They are assigned without spaces around the sign =:

bash
nome="Hackita"
echo $nome

Il $ in front of the name is used for read the value. Without $ you're just naming the variable.

Bash also comes with pre-built environment variables:

bash
echo $HOME    # la tua cartella home
echo $PATH    # dove Bash cerca gli eseguibili
echo $USER    # il tuo nome utente

$PATH This is the list of directories Bash looks for a binary in when you type a command. If you type nmap and it works, it's because the executable is located in one of the folders listed in $PATH.

Quoting: single, double, and no quotes #

Point that almost everyone stumbles on at the beginning.

bash
nome="Hackita"
echo "Ciao $nome"     # Ciao Hackita -> la variabile viene espansa
echo 'Ciao $nome'     # Ciao $nome -> testo letterale, niente espansione
echo Ciao $nome       # funziona ma è rischioso con spazi/caratteri speciali

Rule of thumb: always use "$variabile" with double quotes, especially with paths or external input. Leaving a variable unquoted is one of the most common causes of scripts breaking on spaces or special characters—or, in the worst case, executing a command other than the one intended.

Redirection, pipes and stdin/stdout/stderr #

Each Bash process has three communication channels, identified by a number:

text
stdin  → 0  (input)
stdout → 1  (output normale)
stderr → 2  (output di errore)

Redirection commands:

bash
ls > lista.txt        # salva stdout in un file (sovrascrive)
ls >> lista.txt        # aggiunge stdout alla fine del file
cat < lista.txt         # legge il file come input (stdin)
comando1 | comando2     # passa stdout di comando1 come stdin a comando2

You can also manage channels separately:

bash
comando > output.txt          # solo stdout nel file
comando 2> errori.txt          # solo stderr nel file
comando > output.txt 2>&1      # sia stdout che stderr nello stesso file
comando 2>/dev/null             # scarta gli errori

Practical example:

bash
cat /etc/passwd | grep bash

It reads: “show me the contents of /etc/passwd, then filter out only lines containing 'bash'.”

Control Operators: &&, ||, ; #

They are used to chain commands based on their outcome:

bash
comando1 && comando2   # esegue comando2 solo se comando1 ha successo
comando1 || comando2   # esegue comando2 solo se comando1 fallisce
comando1 ; comando2    # esegue entrambi, indipendentemente dal risultato del primo

These operators tie directly into the concept of exit codes, explained later.

File permissions #

Every file in Linux has read (r), write (w), and execute (x) permissions, assigned to the owner, group, and other users.

bash
ls -l file.sh
-rwxr-xr-- 1 utente utente 220 set 13 10:00 file.sh

It reads: owner can read/write/execute, group can read/execute, others only read.

To change them:

bash
chmod +x script.sh            # rendi eseguibile
chmod 750 script.sh            # permessi numerici precisi
chown utente:gruppo file.sh    # cambia proprietario

Permissions aren't a bureaucratic detail: an overly permissive configuration on a script executed as root is one of the most common gateways to privilege escalation. Complete guide: Linux privilege escalation.

Conditionals #

bash
if [[ -f "$file" ]]; then
    echo "Il file esiste"
else
    echo "Il file non esiste"
fi

Common tests: -f (it's a file), -d (it's a folder), -x (it is executable), -z (empty string), -eq/-ne (equal/different between numbers).

Note on [[ ]] vs [ ]: [ ] It is the classic POSIX test, [[ ]] is a Bash extension with more robust syntax (no quoting problems with empty variables, support for &&/|| internals). In Bash scripts, you prefer [[ ]].

cycles #

bash
for i in 1 2 3; do
    echo "Numero: $i"
done
bash
while [[ $contatore -lt 5 ]]; do
    echo $contatore
    contatore=$((contatore + 1))
done

Functions #

bash
saluta() {
    local nome="$1"
    echo "Ciao $nome"
}

saluta "Hackita"

$1 is the first argument passed to the function, $2/$3 they follow the same logic, $@ represents all the arguments together. local limits the variable to the function scope, preventing it from polluting the global environment of the script.

Write and run a script #

A script is a text file, typically with the extension .sh, which contains a sequence of commands.

bash
#!/usr/bin/env bash
# Questo script stampa la data e i file nella cartella corrente

echo "Oggi è: $(date)"
ls

The first line (#!/usr/bin/env bash) is the shebang: tells the system which interpreter to use to run the file.

To launch it:

bash
chmod +x mioscript.sh
./mioscript.sh

Exit code and error handling #

Each process, when it terminates, returns an exit status: conventionally 0 indicates success, a value different from 0 indicates an error condition or otherwise an unsuccessful outcome according to the program.

bash
ls /cartella/inesistente
echo $?

$? Displays the exit code of the last command executed. This is useful not only for debugging, but also for making the script respond to a failure:

bash
if ! cp "$origine" "$destinazione"; then
    echo "Errore durante la copia" >&2
    exit 1
fi

Much more useful than just manually controlling $? after each command.

trap #

trap performs an action when the script receives a signal or terminates, useful for cleaning up temporary files or handling a forced termination (e.g. Ctrl+C):

bash
cleanup() {
    rm -f "$tmpfile"
}

trap cleanup EXIT

Best practices for Bash scripts #

Some tricks that significantly increase the reliability of a script:

bash
#!/usr/bin/env bash
set -euo pipefail
  • set -e: abort the script on the first command that fails
  • set -u: break the script if you use an undefined variable
  • set -o pipefail: causes a pipe to fail if any command within it fails, not just the last one

Other precautions:

bash
readonly COSTANTE="valore"   # variabile non modificabile
local variabile              # variabile locale a una funzione

if [[ $# -lt 1 ]]; then
    echo "Uso: $0 <file>"
    exit 1
fi

And, as already said: always quote variables with "$variabile".

Before considering a ready-made script, it's worth running it through ShellCheck , a static analyzer that automatically catches quoting errors, unused variables, and other common pitfalls in Bash scripts.

Bash and cybersecurity #

Bash isn't just a convenience for sysadmins. In an offensive context—always in authorized labs like HackTheBox or test environments for which you have explicit permission—Bash comes into play in several places:

Enumeration automation. Bash script to sequentially launch scans, collect output, and filter it automatically, instead of repeating commands manually.

File and log analysis. Pipe with grep, sort, uniq, awk to extract useful information from logs and configuration files during post-exploitation analysis.

Process and Permission Management. Understanding file permissions and ownership is the foundation for identifying privilege escalation vectors.

LOLBins and binaries with elevated permissions. Many binaries that invoke a shell within them, if run with elevated privileges (e.g., via sudo or SUID), allow you to obtain a privileged shell. Concrete examples on GTFOBins.

Misconfigured cron jobs. Bash scripts run by root via cron, with unquoted variables or relative paths, are a real source of real-world vulnerabilities. Learn more about crontab.

Reverse shell. Several one-liner reverse shells exploit Bash's file descriptor redirection to open a connection to an attacker's machine.

Command execution and reverse shell techniques should only be used on your own systems or in environments for which you have explicit authorization.

Bash FAQ #

Is Bash a programming language? Bash is primarily a shell, but it includes features—variables, conditionals, loops, functions, error handling—that allow you to write actual scripts.

Is Bash the same as the terminal? No. The terminal is the interface through which you interact with a shell. Bash is one of the shells you can run inside the terminal.

Does Bash only work on Linux? No. It's available on several Unix-like systems and can also be used on macOS and, through dedicated environments, on Windows.

What is Bash used for? To execute commands, administer systems, manipulate files, automate tasks, and write scripts.

Is Bash difficult to learn? The basic commands are relatively simple. The more complex parts come with quoting, redirection, process and error handling, and advanced scripting.

Is Bash useful for ethical hacking? Yes, especially for automation, enumeration, and scripting during authorized security tasks.

How to continue studying #

text
Terminale
   ↓
File e directory
   ↓
Pipe e redirezione
   ↓
Variabili e quoting
   ↓
Condizioni e cicli
   ↓
Funzioni
   ↓
Exit code e gestione errori
   ↓
Scripting avanzato
   ↓
Bash e sicurezza

From here, the natural steps are to delve into the 100 most used Linux commands , understand how Linux privilege escalation often exploits its own scripts and misconfigured permissions, and study GTFOBins and crontab to see Bash applied concretely in an offensive context.

#bash #shell #linux #terminale #sysadmin

leave a message

I'm not a robot