Bash Aliases, Functions, and Environment Variables
I customized the shell with aliases, small functions, and exported environment variables to cut keystrokes and standardize tool behaviour across hosts. Centralizing PATH and tool defaults in one sourced file gave every session a consistent, productive baseline.
Objective & Context
The environment shapes how every command runs. This lab covers aliases for shorthand, functions for parameterized shortcuts, and exported variables (PATH, EDITOR, history settings), the personalization layer the startup-files lab makes persistent.
Learning Objectives
- Define aliases for frequently typed commands and commands with flags.
- Write shell functions for parameterized shortcuts aliases cannot express.
- Export environment variables and explain export versus plain assignment.
- Customize PATH, EDITOR, and history behavior safely.
- Verify variable inheritance in child processes.
Environment & Prerequisites
Prerequisites
- A Bash shell with a writable home directory.
- Understand the difference between shell variables and environment variables (covered here).
- One tool you invoke often, to turn into an alias or function.
- No packages to install; this lab uses shell builtins only.
Step-by-Step Execution
1. Define aliases and a function
alias ll='ls -lAh'; gco() { git checkout "$1"; }Expected output:
$ type ll
ll is aliased to `ls -lAh'
$ gco main
Switched to branch 'main'
What this teaches: Aliases are pure text substitution, expanded before anything else runs; functions take positional parameters ($1), which is why gco can accept a branch name and an alias cannot. Run the gco test inside a git repository, since git checkout needs one to switch branches.
2. Export environment variables
export EDITOR=vim; export PATH="$HOME/.local/bin:$PATH"Expected output:
$ echo $EDITOR
vim
$ echo $PATH
/home/taki/.local/bin:/usr/local/bin:/usr/bin:/bin
What this teaches: export marks a variable for inheritance by child processes; prepending to PATH puts your personal bin first so your scripts shadow system ones deliberately.
3. Verify inheritance in a child shell
bash -c 'echo $EDITOR'Expected output:
vim
What this teaches: A child shell inherits only exported variables, which is why EDITOR survives but a plain VAR=1 assignment does not. This inheritance model is how every program gets its environment.
4. Persist the setup in ~/.bashrc and tune history
cat >> ~/.bashrc <<'EOF'
alias ll='ls -lAh'
export EDITOR=vim
export PATH="$HOME/.local/bin:$PATH"
HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoredups:erasedups
shopt -s histappend
EOF
source ~/.bashrc
Expected output:
$ echo $HISTSIZE
5000
$ type ll
ll is aliased to `ls -lAh'
What this teaches: Settings typed at the prompt die with the shell, so persistent customization goes in ~/.bashrc, which every interactive Bash reads at startup. source reloads it into the current shell without logging out. The history settings keep a larger shared history across sessions while dropping consecutive duplicates. Keep this file in version control or a dotfiles repo so a new machine gets the same environment.
How It Works
Aliases are the shell's simplest customization: text replacement performed before parsing, so alias ll='ls -lAh' turns ll into the longer command wherever it appears. They cannot take arguments, which is exactly the gap functions fill. A function is a named block of shell code with positional parameters, giving you parameterized shortcuts with real logic.
Environment variables are the process inheritance mechanism. When the shell forks a child, exported variables are copied into the child's environment block; unexported ones stay private to the shell. PATH is the most consequential variable because it controls command resolution order, while EDITOR and VISUAL tell tools like crontab -e and visudo which editor to launch.
History tuning rounds out the personalization layer: HISTSIZE and HISTFILESIZE bound memory and disk usage, HISTCONTROL=ignoredups:erasedups keeps the history useful, and shopt -s histappend merges histories across sessions. These live in .bashrc (covered in the startup files lab) so every interactive shell inherits the same behavior.
Validation & Testing
Confirm an alias works in the current shell and that an exported variable is visible to a child process while an unexported one is not. Pass criteria: aliases expand, exported variables inherit, and PATH changes take effect for new commands.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Alias works interactively but not in scripts | Aliases are disabled in non-interactive shells by default | Use a function instead, or enable with shopt -s expand_aliases |
| export had no effect on the running program | The program was started before the export, or in another shell | Export in the same shell session before launching the program |
| PATH change broke basic commands | The new PATH omitted system directories | Always append or prepend, never replace: PATH="$HOME/.local/bin:$PATH" |
| Variable set but child sees it empty | It was assigned without export | Use export VAR=value, or export an existing variable with export VAR |
| Function name shadows a real command | Functions take precedence over PATH lookup | Rename the function or call the binary via command name to bypass |
| Changes vanished after logout | They were set in the current shell only | Persist them in ~/.bashrc for interactive shells |
Advanced: Troubleshooting
- Alias missing in scripts: aliases are not expanded in non-interactive scripts; use functions.
- Var not inherited: only
exported variables pass to child processes. - PATH ordering: earlier entries win; prepend to override system binaries.
Key Results
- Reduced common commands to short, memorable aliases.
- Standardized EDITOR and PATH across all sessions.
- Replaced fragile aliases with functions where parameters were needed.
- Verified export semantics with a child-shell test.
Key Takeaways
- Aliases are text substitution; functions take arguments.
- export is what makes a variable visible to child processes.
- Prepend personal directories to PATH; never replace it outright.
- EDITOR/VISUAL control which editor tools like visudo launch.
- Persist customizations in .bashrc so they survive new shells.
Practice Challenges
Challenge 1: Safe rm
Goal: create an rm alias or function that moves files to ~/.trash instead of deleting, with an undelete helper.
Hint: a function can take multiple arguments; mkdir -p the trash dir first.
Challenge 2: Project environment
Goal: write a function workon that sets PROJECT_DIR, prepends ./bin to PATH, and exports an API endpoint variable for one project.
Hint: functions can export, and you can unset in a matching workoff.