A good .bashrc is invisible — everything just works. A bad one means typing the same 30-character command for the thousandth time.
This is the full setup I run on Ubuntu for Python and AI development. Every command is here with its exact behaviour so you can pick what you need and skip the rest.
To apply any change:
source ~/.bashrc
Shell Options
These go at the top before anything else.
HISTCONTROL=ignoreboth # skip duplicates and lines starting with a space
HISTSIZE=10000 # keep 10k commands in memory
HISTFILESIZE=20000 # keep 20k commands on disk
HISTIGNORE="history*:ls:ll:la:pwd:exit:clear:h:hg"
HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
shopt -s histappend # append to history file, never overwrite
shopt -s checkwinsize # keep terminal size accurate
shopt -s globstar # enables ** for recursive matching
shopt -s autocd # type a directory name to cd into it
shopt -s cdspell # auto-correct minor typos in cd
Why these matter:
HISTSIZE=10000— the default Ubuntu value is 1000, which means useful commands from last week are goneHISTTIMEFORMAT— every history entry now shows an exact timestamp, useful for debugging “when did I run that?”globstar— lets you writels **/*.pyto find all Python files recursively withoutfindautocd— typeprojectsinstead ofcd projectscdspell—cd Doucmentssilently corrects tocd Documents
File Listing
alias ls='ls --color=auto --human-readable --classify --group-directories-first'
alias ll='ls -alF --group-directories-first' # long, all files, dirs first
alias la='ls -A' # all except . and ..
alias l='ls -CF' # compact columns
alias lt='ls -ltr --group-directories-first' # sorted by time, newest last
alias lS='ls -lSr --group-directories-first' # sorted by size, largest last
| Command | Use case |
|---|---|
ls | Regular listing — human-readable sizes, dirs first |
ll | Full details — permissions, owner, size, date |
la | See hidden files without the noise of . and .. |
lt | What changed recently? Newest file at the bottom |
lS | What is taking up space? Largest at the bottom |
--group-directories-first on every listing command is the single most useful ls change — directories are always at the top, never buried among files.
Safer Core Commands
alias cp='cp -iv' # ask before overwriting, show what was copied
alias mv='mv -iv' # ask before overwriting, show what was moved
alias mkdir='mkdir -pv' # create parent directories automatically, print what was made
alias df='df -h --total'
alias du='du -h --max-depth=1 | sort -hr'
alias free='free -h --si'
alias ps='ps aux --sort=-%cpu'
alias top='command -v htop &>/dev/null && htop || top'
alias cat='command -v batcat &>/dev/null && batcat --style=plain || cat'
| Command | What changed |
|---|---|
cp / mv | Will ask “overwrite?” before clobbering a file. -v prints each operation. |
mkdir | mkdir a/b/c now works without pre-creating a and b first |
df | Shows a grand total row at the bottom |
du | Only goes one level deep, sorted largest first — much more useful than the default |
free | Shows RAM in GB/MB instead of kilobytes |
ps | Shows all processes sorted by CPU — the high-CPU processes appear first |
top | Opens htop if it is installed, falls back to top |
cat | Opens bat if installed (syntax highlighting, line numbers) — plain cat otherwise |
Navigation
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias back='cd -'
mkcd() { mkdir -p "$1" && cd "$1"; }
| Command | What it does |
|---|---|
.. | Up one directory |
... | Up two directories |
.... | Up three directories |
back | Go back to previous directory (same as cd -) |
mkcd project/src | Create the directory tree and land inside it |
mkcd is the one I use the most. Creating a new project directory and immediately being inside it is a daily operation.
History Search
alias h='history | tail -40 | sed "s/^ *[0-9]* //"'
hg() { history | grep --color=auto -i "$*"; }
| Command | What it does |
|---|---|
h | Last 40 commands, clean — no numbers cluttering the output |
hg docker | Search all history for any command containing “docker” |
If fzf is installed, Ctrl+R becomes an interactive fuzzy search through your entire history instead of the default backwards search.
System Info
sysinfo() # full overview
ports() # listening ports
myip() # local IP addresses
psg() # search processes
killport() # kill by port number
sysinfo
sysinfo
Prints OS, kernel, uptime, CPU model, core count, load average, RAM usage, and disk usage in one clean block. Useful at the start of a debugging session.
ports
ports
Shows every port currently being listened on. Replaces ss -tlnp which is hard to remember and hard to read.
myip
myip
Lists all local IPv4 addresses across all interfaces. Useful when you need to share your machine’s address on the local network.
psg
psg python
psg jupyter
Searches running processes by name. Equivalent to ps aux | grep python but cleaner.
killport
killport 3000
killport 8888
Kills whatever process is listening on that port. Common use: Jupyter or a dev server didn’t shut down cleanly.
Git Shortcuts
alias gs='git status -sb'
alias gd='git diff --stat'
alias gdc='git diff --cached --stat'
alias ga='git add'
alias gc='git commit -m'
alias gca='git commit --amend --no-edit'
alias gp='git push'
alias gl='git pull'
alias gb='git branch -vv'
alias gco='git checkout'
alias glog='git log --oneline --graph --decorate --color --all | head -30'
alias gundo='git reset --soft HEAD~1'
alias gclean='git clean -fd'
| Command | What it does |
|---|---|
gs | Short status — branch name + changed files only |
gd | What changed but is not staged yet (summary) |
gdc | What is staged and ready to commit |
ga file.py | Stage a file |
gc "fix: null check" | Commit with a message inline |
gca | Add staged changes to the last commit without editing the message |
gp / gl | Push / pull |
gb | All branches with their upstream tracking status |
glog | Visual branch graph — last 30 commits across all branches |
gundo | Undo last commit but keep all the changes staged |
gclean | Delete all untracked files and directories |
gundo is the most important safety command here. If you committed too early or with the wrong message, gundo puts everything back to staged — nothing is lost.
System Update — u
u
One command that updates everything:
- APT —
apt update,upgrade,autoclean,autoremove - Ollama — re-runs the official install script, restarts the service
- OpenClaw —
npm update -g openclaw, reinstalls gateway service, restarts - npm globals — updates all other globally installed npm packages
Each section is skipped gracefully if the tool is not installed, so this command works on any machine.
━━━ APT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
...
━━━ OLLAMA ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Ollama updated: ollama version 0.18.x
━━━ OPENCLAW ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ OpenClaw updated
━━━ NPM GLOBALS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ All updates complete.
AI Stack — Ollama + OpenClaw
These commands control the local AI setup: Ollama (model runtime) and OpenClaw (WhatsApp AI gateway).
Start / Stop / Restart
ai-start # start both Ollama and OpenClaw
ai-stop # stop both cleanly
ai-restart # restart both, then show status
ai-start starts Ollama first (it takes a moment to be ready), waits, then starts OpenClaw. Both confirm their state after starting.
Status Dashboard
ai-status
━━━ AI Stack Status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
● Ollama running │ 6 model(s) installed │ port 11434
● OpenClaw running │ model: qwen3:8b │ http://127.0.0.1:18789/
Commands: ai-start · ai-stop · ai-restart · ai-logs · ai-models
Logs and Models
ai-logs # follow OpenClaw logs live (Ctrl+C to stop)
ai-models # list all installed Ollama models with sizes
ai-dashboard # open the OpenClaw control UI in browser
ai-logs is the first thing to run when something is not working — it shows every incoming WhatsApp message, model calls, and errors in real time.
Python
Quick Access
alias py='python3'
alias ipy='ipython'
alias pip='pip3'
ipy opens IPython — a much better interactive Python shell than the default. Tab completion, syntax highlighting, %timeit, %paste, magic commands.
Environment Info
pyinfo
━━━ Python Environment ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Executable: /home/neel/neellocal/bin/python3
Version: Python 3.12.3
Pip: pip 24.0
Venv: neellocal (/home/neel/neellocal)
Packages: 84 installed
Useful when you are jumping between environments and want to confirm which Python and which packages are actually active.
Create a Venv
venv myenv # creates ./myenv and activates it
venv # creates ./.venv and activates it (default)
Replaces the two-step python3 -m venv myenv && source myenv/bin/activate. Run deactivate to leave the venv.
Package Management
pip-outdated # list packages that have updates available
pip-upgrade-all # upgrade every package in the current environment
pip-upgrade-all is safe to run regularly in a dev venv. Be more careful in production environments.
Utilities
serve # HTTP server on port 8000 in current directory
serve 9000 # HTTP server on a custom port
json-pretty # pretty-print JSON
json-pretty data.json
cat raw.json | json-pretty
serve is useful for quickly sharing files on a local network, serving a static site build, or testing CORS by serving from a known port.
json-pretty wraps python3 -m json.tool. Pipe any JSON into it or pass a filename.
Conda Environments
envs # list all conda environments
ca open-webui # activate a conda environment
cda # deactivate current conda environment
ml-env # shortcut: activate the open-webui ML environment
base-env # return to the default neellocal venv
What is in ml-env?
The open-webui conda environment contains the full ML stack:
| Package | Version |
|---|---|
| PyTorch | 2.5.1 |
| Transformers (Hugging Face) | 4.46.2 |
| sentence-transformers | 3.3.1 |
| LangChain | 0.3.7 |
| OpenAI SDK | 1.54.4 |
| Anthropic SDK | 0.39.0 |
| Open WebUI | 0.5.12 |
Switch into it when you need these packages:
ml-env
# now torch, transformers, openai, anthropic etc. are available
python3 -c "import torch; print(torch.__version__)"
base-env
# back to the default environment
Jupyter
jl # start JupyterLab, print URL (no browser)
jlab # start JupyterLab + open browser automatically
jn # start classic Notebook interface
jupyter-stop # kill all running Jupyter servers
jl is the one I use most — it prints the URL with the token so I can open it in the browser I choose, or connect to it remotely via SSH tunnel. The --no-browser flag prevents it from trying to open a browser on a headless server.
To run JupyterLab with access to the ML conda environment:
ml-env
jl
GPU Monitoring
gpu # current GPU status
gpu-watch # live monitor, refreshes every second
torch-info # PyTorch CUDA availability check
gpu
━━━ GPU Status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
NVIDIA GeForce RTX 3080 52°C GPU:34% VRAM:4821MiB/10240MiB Power:180W
One line per GPU. If the driver is not loaded it tells you clearly rather than showing a confusing error.
gpu-watch
gpu-watch
Runs nvidia-smi in a live watch loop. Useful while training a model to monitor VRAM and utilisation.
torch-info
# Run this inside ml-env
ml-env
torch-info
PyTorch: 2.5.1
CUDA: available (12.1)
GPU 0: NVIDIA GeForce RTX 3080 10240 MiB
If PyTorch is not available in the current environment it tells you to run ml-env first.
Archive Extraction
extract file.tar.gz
extract file.zip
extract file.tar.bz2
extract file.7z
One command for every archive format. No more looking up which flags tar needs for which extension.
Supports: .tar.gz, .tar.bz2, .tar.xz, .tar, .bz2, .gz, .zip, .7z, .rar.
Miscellaneous
please # re-run the previous command with sudo
back # go to the previous directory
week # print current week number (e.g. 11)
timestamp # print 20260318_143022 — useful for filenames
please is the most satisfying command in this list. Run a command, get permission denied, type please, done.
Installation
The following tools should be installed for the full experience:
sudo apt-get install -y htop bat tree ncdu fzf
| Tool | Replaces | Benefit |
|---|---|---|
htop | top | Interactive process viewer with colours |
bat | cat | Syntax highlighting, line numbers, git integration |
tree | manual find | Directory tree visualisation |
ncdu | du | Interactive disk usage browser |
fzf | Ctrl+R | Fuzzy search through history and files |
The .bashrc detects these tools automatically — no changes needed after installing them.