# Press Ctrl+R, then type 'docker'
(reverse-i-search)`docker': docker compose up -d --build
Note Press Ctrl+R again to cycle through older matches. Enter executes the found command. Ctrl+G or Esc cancels the search. This is one of the biggest timesavers in daily terminal work.
!! # last command
!$ # last argument of previous command
!n # command number n
!string# last command starting with string
example
apt install nginx
sudo !!
# Expands to: sudo apt install nginx
mkdir /opt/new-app
cd !$
# Expands to: cd /opt/new-app
!grep# Reruns last command that started with 'grep'
Note !! is indispensable when you forget sudo. !$ avoids retyping long paths. Use !:n to reference a specific argument (e.g., !:2 for the second). Add :p to preview without executing: !!:p shows what would run.
bang bangrepeat last commandsudo last commandlast argumenthistory expansion
Create Command Aliases
syntax
alias name='command'
unalias name
example
alias ll='ls -lah'
alias gs='git status'
alias dc='docker compose'
alias k='kubectl'
alias myip='curl -s ifconfig.me'
Note Aliases defined in the terminal are lost when the shell exits. Add them to ~/.bashrc or ~/.zshrc to make them permanent. Run alias with no arguments to list all current aliases. Use unalias to remove one.
# Add to ~/.bashrc or ~/.zshrc:export PATH="$HOME/.local/bin:$PATH"export EDITOR=vim
alias deploy='cd ~/projects/main && ./deploy.sh'# Reload after editing:
source ~/.bashrc
Note .bashrc runs for every new interactive Bash shell. .bash_profile runs only for login shells. .zshrc runs for every interactive Zsh shell. After editing, run source ~/.bashrc (or source ~/.zshrc) to apply changes without opening a new terminal.
Note config.yml{,.bak} expands to 'config.yml config.yml.bak', making a quick backup. Brace expansion happens before variable expansion, so you cannot use variables inside braces. Ranges support zero-padding ({01..12}) and steps ({0..20..5}).
brace expansiongenerate sequencequick backupcreate multiple filesnumber range
Command Substitution
syntax
$(command)
`command` (legacy)
example
echo"Today is $(date '+%A, %B %d')"
BRANCH=$(git rev-parse --abbrev-ref HEAD)
FILES_CHANGED=$(git diff --name-only | wc -l)echo"${FILES_CHANGED} files changed on ${BRANCH}"
output
Today is Saturday, April 04
3 files changed on feature/auth
Note Always use $() instead of backticks. $() nests cleanly: $(echo $(whoami)) works; backticks require escaping for nesting. The output has trailing newlines stripped automatically.
# Add to ~/.bashrc or ~/.zshrc:export CDPATH=".:$HOME/projects:$HOME/work"# Now from anywhere:cd web-app
# Jumps to ~/projects/web-app without typing the full path
Note CDPATH tells cd to search additional base directories. The leading . ensures the current directory is still checked first. Separate paths with colons. This drastically reduces typing for developers who frequently switch between project directories.
cdpathquick navigationfast cddirectory shortcutjump to project
Ctrl+A → move cursor to beginning of line
Ctrl+E → move cursor to end of line
Ctrl+U → deletefrom cursor to beginning
Ctrl+K → deletefrom cursor to end
Ctrl+W → delete previous word
Ctrl+L → clear screen (same as clear)
Ctrl+C → cancel current command
Ctrl+D → exit shell (or send EOF)
Ctrl+Z → suspend foreground process
Alt+. → insert last argument from previous command
Note These work in both Bash and Zsh and are based on Emacs keybindings (the default). Alt+. is one of the most underused shortcuts; it cycles through previous commands' last arguments. Use set -o vi in your shell config to switch to Vim-style keybindings.
cd /etc/ng<Tab>
# Completes to: cd /etc/nginx/git che<Tab><Tab>
# Shows: checkout cherry cherry-pick
Note Tab completion works for commands, file paths, and (with bash-completion or zsh plugins) for subcommands and flags of many tools including git, docker, kubectl, and ssh hosts. Install bash-completion for enhanced support in Bash.