Neel Shah
All posts
DevOps 10 min read March 18, 2026

My Ubuntu .bashrc for Python, AI, and Daily Development

Every command, alias, and function in my .bashrc — covering file navigation, git, system info, AI stack control, Python environments, Jupyter, GPU monitoring, and a single update command for everything.

UbuntuBashDeveloper SetupPythonAIProductivity
Neel Shah
Tech Lead · Senior Data Engineer · Ottawa

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 gone
  • HISTTIMEFORMAT — every history entry now shows an exact timestamp, useful for debugging “when did I run that?”
  • globstar — lets you write ls **/*.py to find all Python files recursively without find
  • autocd — type projects instead of cd projects
  • cdspellcd Doucments silently corrects to cd 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
CommandUse case
lsRegular listing — human-readable sizes, dirs first
llFull details — permissions, owner, size, date
laSee hidden files without the noise of . and ..
ltWhat changed recently? Newest file at the bottom
lSWhat 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'
CommandWhat changed
cp / mvWill ask “overwrite?” before clobbering a file. -v prints each operation.
mkdirmkdir a/b/c now works without pre-creating a and b first
dfShows a grand total row at the bottom
duOnly goes one level deep, sorted largest first — much more useful than the default
freeShows RAM in GB/MB instead of kilobytes
psShows all processes sorted by CPU — the high-CPU processes appear first
topOpens htop if it is installed, falls back to top
catOpens bat if installed (syntax highlighting, line numbers) — plain cat otherwise

alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias back='cd -'

mkcd() { mkdir -p "$1" && cd "$1"; }
CommandWhat it does
..Up one directory
...Up two directories
....Up three directories
backGo back to previous directory (same as cd -)
mkcd project/srcCreate 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.


alias h='history | tail -40 | sed "s/^ *[0-9]* //"'
hg() { history | grep --color=auto -i "$*"; }
CommandWhat it does
hLast 40 commands, clean — no numbers cluttering the output
hg dockerSearch 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'
CommandWhat it does
gsShort status — branch name + changed files only
gdWhat changed but is not staged yet (summary)
gdcWhat is staged and ready to commit
ga file.pyStage a file
gc "fix: null check"Commit with a message inline
gcaAdd staged changes to the last commit without editing the message
gp / glPush / pull
gbAll branches with their upstream tracking status
glogVisual branch graph — last 30 commits across all branches
gundoUndo last commit but keep all the changes staged
gcleanDelete 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:

  1. APTapt update, upgrade, autoclean, autoremove
  2. Ollama — re-runs the official install script, restarts the service
  3. OpenClawnpm update -g openclaw, reinstalls gateway service, restarts
  4. 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:

PackageVersion
PyTorch2.5.1
Transformers (Hugging Face)4.46.2
sentence-transformers3.3.1
LangChain0.3.7
OpenAI SDK1.54.4
Anthropic SDK0.39.0
Open WebUI0.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
ToolReplacesBenefit
htoptopInteractive process viewer with colours
batcatSyntax highlighting, line numbers, git integration
treemanual findDirectory tree visualisation
ncduduInteractive disk usage browser
fzfCtrl+RFuzzy search through history and files

The .bashrc detects these tools automatically — no changes needed after installing them.