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.txt
write STDOUT to file -
cmd >> out.txt
append -
cmd < in.txt
read STDIN from file -
cmd 2> err.txt
write STDERR to file -
cmd > all.txt 2>&1
merge STDERR into STDOUT -
a | b | c
connect outputs to inputs through pipes -
tee
to 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'
-
-e
exit on unhandled error -
-u
error on unset vars -
-o pipefail
propagate pipeline failures -
IFS
tuned 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 -print0
andmapfile
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/profile
then~/.bash_profile
(or~/.profile
). -
Interactive non-login shells (typical new terminal) read
~/.bashrc
. -
Non-interactive shells (scripts) read
BASH_ENV
if 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 > file
fails 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 nullglob
when 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