Skip to main content
TellaDev
Learn Terminal Shell Productivity Tricks
beginner Terminal

Shell Productivity Tricks

Speed up your terminal workflow with aliases, functions, history search, and keyboard shortcuts.

Biplab Adhikari 811 words
shell aliases productivity zsh bash dotfiles
Shell Productivity Tricks

Aliases

An alias is a shortcut for a longer command. Define them in your shell config file and they’re available every time you open a terminal.

Where to put them:

  • Bash: ~/.bashrc (Linux) or ~/.bash_profile (macOS)
  • Zsh: ~/.zshrc
# Navigation shortcuts
alias ..='cd ..'
alias ...='cd ../..'
alias ~='cd ~'

# Git shortcuts
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gpl='git pull'
alias gl='git log --oneline --graph --decorate'
alias gd='git diff'
alias gcb='git checkout -b'

# List files with color and human-readable sizes
alias ls='ls --color=auto'
alias ll='ls -lahF'
alias la='ls -A'

# Safety nets
alias rm='rm -i'           # Prompt before deleting
alias cp='cp -i'           # Prompt before overwriting
alias mv='mv -i'           # Prompt before overwriting

# Quick edits
alias zshrc='${EDITOR:-nano} ~/.zshrc'
alias bashrc='${EDITOR:-nano} ~/.bashrc'
alias reload='source ~/.zshrc'    # or ~/.bashrc

After adding aliases, reload your config:

source ~/.zshrc   # or: exec $SHELL

Shell Functions

When an alias isn’t powerful enough (you need arguments, logic, or multiple commands), use a function:

# Create a directory and immediately cd into it
mkcd() {
  mkdir -p "$1" && cd "$1"
}
# Usage: mkcd projects/new-app

# Search for a process and kill it by name
killnamed() {
  pkill -f "$1" && echo "Killed processes matching: $1"
}
# Usage: killnamed node

# Quick git commit with a message
gcm() {
  git add -A && git commit -m "$*"
}
# Usage: gcm Fix login redirect bug

# Extract any archive format
extract() {
  case "$1" in
    *.tar.gz|*.tgz) tar -xzf "$1" ;;
    *.tar.bz2)      tar -xjf "$1" ;;
    *.zip)          unzip "$1" ;;
    *.gz)           gunzip "$1" ;;
    *.rar)          unrar x "$1" ;;
    *)              echo "Unknown format: $1" ;;
  esac
}
# Usage: extract archive.tar.gz

# Show listening ports
ports() {
  lsof -i -P -n | grep LISTEN
}

Add these to your ~/.zshrc or ~/.bashrc, then source it.


Your shell remembers thousands of past commands. Use that history instead of retyping.

Ctrl + R — Reverse history search (most useful)

# Press Ctrl+R and start typing
(reverse-i-search)`docker`: docker compose up -d

# Press Ctrl+R again to cycle through older matches
# Press Enter to run the found command
# Press Ctrl+G to cancel

History expansion shortcuts:

!!         # Repeat the last command
!$         # Last argument of the last command
!^         # First argument of the last command
!string    # Most recent command starting with "string"
!?string   # Most recent command containing "string"

Practical examples:

sudo !!                        # Re-run last command with sudo
cat /etc/nginx/nginx.conf
vi !$                          # Edit /etc/nginx/nginx.conf (last arg)

mkdir -p projects/new-app
cd !$                          # cd projects/new-app

git commit -m "Initial commit"
!git                           # Repeats last git command

Search and print without running:

!docker:p    # Print the last docker command without running it

Directory Navigation

# Jump to the previous directory
cd -

# Jump to home directory
cd        # or cd ~

# Push/pop directory stack
pushd ~/projects    # Jump to ~/projects, remember previous dir on stack
pushd /tmp          # Jump to /tmp, remember ~/projects
popd                # Back to ~/projects
popd                # Back to the original directory
dirs -v             # Show the directory stack

Consider installing zoxide — a smarter cd replacement that learns your most-visited directories:

# After installing zoxide and adding eval "$(zoxide init zsh)" to .zshrc:
z proj        # Jumps to ~/projects (or wherever "proj" matches most)
z src/comp    # Fuzzy match to src/components

Useful One-Liners

# Run the last command as sudo
sudo !!

# Copy a file's contents to the clipboard
cat file.txt | pbcopy           # macOS
cat file.txt | xclip -selection clipboard  # Linux

# Find and replace in all files in a directory
sed -i 's/old-text/new-text/g' src/**/*.ts

# Show disk usage of each directory, sorted by size
du -sh */ | sort -h

# Watch a command refresh every 2 seconds
watch -n 2 'docker ps'

# Generate a random password
openssl rand -base64 32

# Show which process is using a port
lsof -i :3000

# Count occurrences of a word in a file
grep -c "error" server.log

# Tail all logs in a directory
tail -f logs/*.log

Managing Dotfiles

Your shell config files (~/.zshrc, ~/.bashrc, ~/.gitconfig, etc.) are called dotfiles. Keeping them in version control means you can restore your setup on any new machine in minutes.

Simple approach: git repo with symlinks

# Create a dotfiles repo
mkdir ~/dotfiles && cd ~/dotfiles
git init

# Move your configs into the repo
mv ~/.zshrc ~/dotfiles/zshrc
mv ~/.gitconfig ~/dotfiles/gitconfig

# Symlink them back
ln -s ~/dotfiles/zshrc ~/.zshrc
ln -s ~/dotfiles/gitconfig ~/.gitconfig

# Push to GitHub for backup
git add -A && git commit -m "Initial dotfiles"
git remote add origin https://github.com/you/dotfiles.git
git push -u origin main

On a new machine:

git clone https://github.com/you/dotfiles.git ~/dotfiles
cd ~/dotfiles
ln -s ~/dotfiles/zshrc ~/.zshrc
ln -s ~/dotfiles/gitconfig ~/.gitconfig
# etc.

For a more automated setup, explore tools like chezmoi or GNU Stow which handle the symlinking automatically.

Build Productivity Slowly

Shell productivity should remove friction, not create a private language nobody else can read. Add one alias or function at a time, use it for a week, and delete it if it does not stick. A bloated shell config becomes another system you have to maintain.

Start with aliases for commands you already type every day. Git status, listing files, jumping to a projects directory, and reloading your shell config are good candidates. Avoid aliases that hide dangerous behavior. A short alias for rm -rf saves almost no time and increases risk.

Keep Config Portable

Your shell config should survive a new laptop. Prefer environment variables for machine-specific paths, and keep optional tool setup guarded so a missing command does not break your shell startup.

For example, if you use a tool like zoxide, initialize it only when the command exists. That keeps the same dotfiles usable on work machines, personal machines, containers, and remote servers where the tool may not be installed.

Debugging A Slow Shell

If a new terminal window takes several seconds to open, your shell config is doing too much work at startup. Common causes include network calls, package manager initialization, loading large prompt frameworks, or running commands that scan the filesystem.

Temporarily comment out sections of your config until startup is fast again, then add them back one at a time. Lazy-load expensive tools where possible. A shell prompt should feel instant because you open it constantly throughout the day.

Team-Friendly Shortcuts

Aliases are personal, but scripts in a repository are shared. If a shortcut is required to build, test, or deploy a project, put it in package.json, a Makefile, a task runner, or a documented script. Do not make teammates depend on your private alias names.

Use shell functions for personal workflow and project scripts for team workflow. That boundary keeps your machine pleasant without making the codebase mysterious.

What I Would Do In Practice

I would keep a small dotfiles repository with shell config, Git config, editor settings, and install notes. I would add only the aliases I actually use: a few Git shortcuts, safer file operations, project navigation, and a command to reload the config.

Every few months, I would remove shortcuts I no longer use. Productivity tooling should feel like a clean workbench. If you cannot explain what a line in your shell config does, it probably does not belong there.

A Practical Upgrade Path

Upgrade your shell in layers. First, make navigation faster with a projects directory, fuzzy search, or a directory-jumping tool. Next, make common project commands discoverable with scripts such as npm run test, make dev, or just build. Then add personal aliases only for commands you already understand.

The warning sign is when a new terminal on a different machine feels unusable. Good shell productivity should make your main machine nicer without making you helpless elsewhere. Keep a plain-English note beside your dotfiles that explains what each major section does and how to disable it.

For teams, document shared commands in the repository instead of in a private shell profile. A shortcut that only works on one person’s laptop is not automation; it is hidden knowledge.

Measure The Time Saved

The best shortcuts remove repeated decisions. If an alias saves two seconds but makes commands harder to understand, it is probably not worth keeping. If a function prevents a recurring mistake, such as deploying from the wrong branch or forgetting a test flag, it is valuable even if it is only used once a day.

Keep a short changelog for major dotfile changes. When a prompt framework, plugin, or completion script slows startup, you will know what changed recently and can undo it quickly.

Review the setup monthly and remove anything that no longer earns its place.