Unix - UNIX shell
What is a shell?
A shell is both:
-
a command-line interface (you type commands, it runs them), and
-
a scripting language (you write programs in it to automate work).
It sits between you and the kernel. You type a command; the shell parses it, performs expansions and redirections, sets up pipelines, and then either runs a builtin (inside the shell process) or launches an external program via the kernel.
Popular shells (quick map)
-
sh: Original Bourne shell; portable scripts.
-
bash: Bourne Again SHell (very common on Linux); arrays,
[[ ]], brace expansion, history, job control. -
ksh: Korn shell; strong in scripting, arithmetic.
-
csh/tcsh: C-like syntax; interactive niceties, less favored for scripting.
-
zsh: Powerful completion/prompt; great interactive experience.
Check your shell: echo "$SHELL" or for a user: getent passwd "$USER".
What happens when you run a command
Example:
grep -i "error" /var/log/syslog | awk '{print $1,$2}' > errors.txt
Under the hood:
-
Lexing & parsing — the shell splits the line into commands and operators (
|,>). -
Expansions — quotes handled; variables/
$(...)/$((...))/globs resolved. -
Redirections & FDs —
>redirects STDOUT (file descriptor 1) toerrors.txt. -
Pipelines — shell creates a pipe; connects
grep’s STDOUT toawk’s STDIN. -
Execution — for each external command, shell does
fork()thenexecve(); the kernel loads the program. -
Exit status —
$?holds the last program’s exit code (0 = success).
Builtins vs external programs
-
Builtins run inside the shell:
cd,echo,readonly,export,alias,type,jobs,ulimit. -
External tools are separate executables found via
$PATH:ls,cp,grep,awk,sed,tar, etc.
See which you’re calling: type cd, type echo, type grep.
Redirection & pipelines (FDs 0/1/2)
-
cmd > out.txtwrite STDOUT to file -
cmd >> out.txtappend -
cmd < in.txtread STDIN from file -
cmd 2> err.txtwrite STDERR to file -
cmd > all.txt 2>&1merge STDERR into STDOUT -
a | b | cconnect outputs to inputs through pipes -
teeto both screen and file:cmd | tee log.txt
Variables, quoting, and expansions
name="Ada Lovelace" # no spaces around =
echo "$name" # double quotes preserve spaces, expand variables
echo 'literal $name' # single quotes prevent expansion
echo "Today is $(date)" # command substitution
echo $((3 * (4 + 5))) # arithmetic
printf '%s\n' *.txt # pathname expansion (globbing)
Export to children: export PATH="$HOME/bin:$PATH".
Shell scripting essentials
-
Shebang: first line picks the interpreter
#!/usr/bin/env bash -
Make it executable:
chmod +x script.sh -
Run:
./script.sh(orbash script.sh)
A robust template often starts with:
set -euo pipefail
IFS=$'\n\t'
-
-eexit on unhandled error -
-uerror on unset vars -
-o pipefailpropagate pipeline failures -
IFStuned for safe word-splitting
A complete, practical example script
I’ve prepared a thoroughly commented script that demonstrates:
-
options with
getopts -
variables, arrays, functions
-
error handling with
trap -
pipelines, redirection,
tee -
here-documents
-
safe file handling with
find -print0andmapfile
You can run it like:
./shell_example.sh -s /var/log -d ~/backups -p "*.log"
./shell_example.sh -s ./data -d ./out -n # dry run
Job control (interactive superpower)
-
Run in background:
long_task & -
Suspend:
Ctrl+Z -
Bring to foreground/background:
fg,bg -
List:
jobs -
Keep running after logout:
nohup cmd &ordisown
Login vs interactive vs non-interactive shells (Bash example)
-
Login shells read
/etc/profilethen~/.bash_profile(or~/.profile). -
Interactive non-login shells (typical new terminal) read
~/.bashrc. -
Non-interactive shells (scripts) read
BASH_ENVif set.
A common setup is: in ~/.bash_profile, source ~/.bashrc so both paths share aliases, prompt, etc.
Common pitfalls (and fixes)
-
Spaces in assignments:
x=5✅ vsx = 5❌ -
Quoting: quote
"$var"unless you intentionally want word-splitting/globbing. -
Redirection with sudo:
sudo cmd > filefails if you can’t writefile. Usesudo sh -c 'cmd > file'orcmd | sudo tee file. -
[vs[[(Bash): prefer[[ ... ]]for safer conditionals. -
Globs on empty matches: consider
shopt -s nullglobwhen appropriate.
At-a-glance cheat sheet
-
Find programs:
which,type,command -v -
Measure time:
time cmd -
Functions:
myfunc(){ local x=$1; echo "$x"; } -
Conditionals:
if [[ -f file && -r file ]]; then ...; fi -
Loops:
for f in *.txt; do echo "$f"; done while read -r line; do ...; done < input.txt