# ~/.bashrc # # Main Bash startup file for interactive shells. # Keep this file small. Put aliases, functions, prompt, # completion, and machine-specific settings in separate files. # # The relevant files are: # - $HOME/.bash_env # - $HOME/.bash_aliases # - $HOME/.bash_functions # - $HOME/.bash_prompt # - $HOME/.bash_completion_extra (do NOT name .bash_completion) # - $HOME/.bash_local # # Not sourced in .bashrc, but important: # - $HOME/.inputrc (set -o vi) # ------------------------------------------------------------ # Stop here if this is not an interactive shell. # # $- contains the current shell option flags. # Interactive shells include the letter "i". # # This prevents aliases, prompts, completion, and other # interactive-only settings from affecting scripts, scp, # cron jobs, or non-interactive shells. # ------------------------------------------------------------ case $- in *i*) ;; *) return ;; esac # ------------------------------------------------------------ # Bash shell options # ------------------------------------------------------------ # Switch to vi keybindes in bash (see also .inputrc) set -o vi # Check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize # Save multi-line commands as one logical command in history. # Example: for-loops and if-blocks stay grouped together. shopt -s cmdhist # Enable recursive globbing with **. # Example: # ls **/*.py # This finds Python files recursively. shopt -s globstar 2>/dev/null # Allow typing a directory name as a command to cd into it. # Example: # ~/projects # behaves like: # cd ~/projects shopt -s autocd 2>/dev/null # ------------------------------------------------------------ # History settings # ------------------------------------------------------------ # Append new history lines to the history file instead of overwriting it. # This is important when using multiple terminal windows. shopt -s histappend # Number of commands kept in memory during the current shell session. HISTSIZE=50000 # Number of commands saved in the history file on disk. HISTFILESIZE=100000 HISTFILE=~/.bash/.bash_history # Controls what gets saved to history. # # ignorespace: # Commands starting with a space are not saved. # Useful for one-off commands containing secrets. # # ignoredups: # Do not save a command if it is the same as the previous command. # # ignoreboth: # Shorthand for ignorespace + ignoredups. # # erasedups: # Remove older duplicate entries when saving a new command. # # Note: # erasedups can be convenient, but it also means you lose older # timestamps for repeated commands. HISTCONTROL=ignoreboth:erasedups # Commands matching these patterns are not saved to history. # This keeps noisy commands from cluttering history. # # Be careful not to ignore too much. History is often useful. HISTIGNORE='ls:ll:la:cd:pwd:exit:history:clear' # Add timestamps to history output. # # %F = YYYY-MM-DD # %T = HH:MM:SS # # Example: # 2026-05-10 14:21:33 git status HISTTIMEFORMAT='%F %T ' # Synchronize history between multiple open terminals. # # That reloads the whole history file every prompt. It gives stronger # cross-terminal sync, but can feel surprising because command ordering # changes more often. # Source: https://unix.stackexchange.com/a/18443 # 2025-03-02 (fbardos) try out another line, source: # https://unix.stackexchange.com/a/1292 PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r" # ------------------------------------------------------------ # Default programs # ------------------------------------------------------------ # Default command-line editor. # # --> see .bash_env # Programs like git, crontab, and some CLI tools read this. # ------------------------------------------------------------ # PATH helpers # ------------------------------------------------------------ # Add a directory to the beginning of PATH only if it exists # and is not already present. # # Prepending means commands in this directory take priority over # system commands with the same name. path_prepend() { [ -d "$1" ] || return case ":$PATH:" in *":$1:"*) ;; *) PATH="$1:$PATH" ;; esac } # Add a directory to the end of PATH only if it exists # and is not already present. # # Appending means system commands still take priority. path_append() { [ -d "$1" ] || return case ":$PATH:" in *":$1:"*) ;; *) PATH="$PATH:$1" ;; esac } # Common place for user-installed executables. # Many tools install command-line binaries here. path_prepend "$HOME/.local/bin" # Traditional personal scripts directory. path_prepend "$HOME/bin" # Export PATH after modifications so child processes inherit it. export PATH # ------------------------------------------------------------ # Load modular Bash config files # ------------------------------------------------------------ # Each file is optional. # [ -r "$file" ] means: # Only source the file if it exists and is readable. # # The order matters: # env first, because later files may depend on variables. # aliases/functions before prompt, because prompt may use functions. # local last, so machine-specific settings can override previous ones. for file in \ "$HOME/.bash_env" \ "$HOME/.bash_aliases" \ "$HOME/.bash_functions" \ "$HOME/.bash_prompt" \ "$HOME/.bash_completion_extra" \ "$HOME/.bash_local" do [ -r "$file" ] && . "$file" done