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
- Bash, Shell, and Terminal: The Difference
- Bash vs sh, Zsh, Fish
- The prompt
- base command
- Variables
- quoting
- Redirection, pipes and stdin/stdout/stderr
- Control Operators:
&&,||,; - File permissions
- Conditionals
- cycles
- Functions
- Write and run a script
- Exit code and error handling
trap- Best practices for Bash scripts
- Bash and cybersecurity
- FAQ
- 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.
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.
| Shell | Main feature |
|---|---|
| sh | Historic Unix shell, the basis of the POSIX standard |
| Bash | Wide compatibility, widespread deployment and mature scripting |
| zsh | Advanced interactivity and customization (default on modern macOS) |
| Fish | Modern 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:
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:
comando [opzioni] [argomenti]Example:
ls -la /homelsis the command (list files and folders)-lathese are the options (show all, long format)/homeit's the topic (where to look)
Commands you'll use every day:
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/rinominaBash doesn't teach you commands; it interprets them. Once you understand the logic of pipes and composition, sequences like this become second nature:
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 =:
nome="Hackita"
echo $nomeIl $ 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:
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.
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 specialiRule 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:
stdin → 0 (input)
stdout → 1 (output normale)
stderr → 2 (output di errore)Redirection commands:
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 comando2You can also manage channels separately:
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 erroriPractical example:
cat /etc/passwd | grep bashIt 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:
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 primoThese 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.
ls -l file.sh
-rwxr-xr-- 1 utente utente 220 set 13 10:00 file.shIt reads: owner can read/write/execute, group can read/execute, others only read.
To change them:
chmod +x script.sh # rendi eseguibile
chmod 750 script.sh # permessi numerici precisi
chown utente:gruppo file.sh # cambia proprietarioPermissions 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 #
if [[ -f "$file" ]]; then
echo "Il file esiste"
else
echo "Il file non esiste"
fiCommon 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 #
for i in 1 2 3; do
echo "Numero: $i"
donewhile [[ $contatore -lt 5 ]]; do
echo $contatore
contatore=$((contatore + 1))
doneFunctions #
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.
#!/usr/bin/env bash
# Questo script stampa la data e i file nella cartella corrente
echo "Oggi è: $(date)"
lsThe first line (#!/usr/bin/env bash) is the shebang: tells the system which interpreter to use to run the file.
To launch it:
chmod +x mioscript.sh
./mioscript.shExit 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.
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:
if ! cp "$origine" "$destinazione"; then
echo "Errore durante la copia" >&2
exit 1
fiMuch 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):
cleanup() {
rm -f "$tmpfile"
}
trap cleanup EXITBest practices for Bash scripts #
Some tricks that significantly increase the reliability of a script:
#!/usr/bin/env bash
set -euo pipefailset -e: abort the script on the first command that failsset -u: break the script if you use an undefined variableset -o pipefail: causes a pipe to fail if any command within it fails, not just the last one
Other precautions:
readonly COSTANTE="valore" # variabile non modificabile
local variabile # variabile locale a una funzione
if [[ $# -lt 1 ]]; then
echo "Uso: $0 <file>"
exit 1
fiAnd, 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 #
Terminale
↓
File e directory
↓
Pipe e redirezione
↓
Variabili e quoting
↓
Condizioni e cicli
↓
Funzioni
↓
Exit code e gestione errori
↓
Scripting avanzato
↓
Bash e sicurezzaFrom 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.







