#!/usr/bin/env bash # EXIT for non-interactive shells (SFTP, SCP, rsync, git, etc.) [[ $- != *i* ]] && return # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi # Enable bash programmable completion features in interactive shells if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi ####################################################### # EXPORTS ####################################################### if [[ $- == *i* ]]; then bind "set bell-style visible" bind "set completion-ignore-case on" bind "set show-all-if-ambiguous On" stty -ixon 2>/dev/null fi # Expand the history size export TERM="xterm-256color" export HISTFILESIZE=10000 export HISTSIZE=10000 export HISTTIMEFORMAT="%F %T" # add timestamp to history export HISTORY_IGNORE="(ls|cd|pwd|exit|sudo reboot|history|cd -|cd ..)" # Don't put duplicate lines in the history and do not add lines that start with a space export HISTCONTROL=erasedups:ignoredups:ignorespace # Check the window size after each command and, if necessary, update the values of LINES and COLUMNS shopt -s checkwinsize shopt -s autocd shopt -s cdspell shopt -s cmdhist shopt -s dotglob shopt -s histappend PROMPT_COMMAND='history -a' # set up XDG folders export XDG_DATA_HOME="${HOME}/.local/share" export XDG_CONFIG_HOME="${HOME}/.config" export XDG_STATE_HOME="${HOME}/.local/state" export XDG_CACHE_HOME="${HOME}/.cache" # Set the default editor alias spico='sudo pico' alias snano='sudo nano' if command -v nvim &>/dev/null; then alias vim='nvim' fi # To have colors for ls and all grep commands such as grep, egrep and zgrep export CLICOLOR=1 export LS_COLORS='no=00:fi=00:di=00;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:*.xml=00;31:' if command -v rg &>/dev/null; then alias grep='rg' fi # Color for manpages in less makes manpages a little easier to read export LESS_TERMCAP_mb=$'\E[01;31m' export LESS_TERMCAP_md=$'\E[01;31m' export LESS_TERMCAP_me=$'\E[0m' export LESS_TERMCAP_se=$'\E[0m' export LESS_TERMCAP_so=$'\E[01;44;33m' export LESS_TERMCAP_ue=$'\E[0m' export LESS_TERMCAP_us=$'\E[01;32m' ####################################################### # GENERAL ALIAS'S ####################################################### # To temporarily bypass an alias, we precede the command with a \ # EG: the ls command is aliased, but to use the normal ls command you would type \ls # alias to show the date alias da='date "+%Y-%m-%d %A %T %Z"' # Alias's to modified commands alias cp='cp -i' alias mv='mv -i' alias rm='rm -i' alias mkdir='mkdir -p' if [[ "$OSTYPE" == darwin* ]]; then alias ps='ps aux' else alias ps='ps auxf' fi alias ping='ping -c 10' alias less='less -R' alias cls='clear' # Change directory aliases alias home='cd ~' alias cd..='cd ..' alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..' alias .....='cd ../../../..' # cd into the old directory alias bd='cd "$OLDPWD"' # Remove a directory and all files alias rmd='\rm -rvf' # Conditional 'ls' alias for 'eza' if command -v eza &>/dev/null; then alias ls='eza -a --classify --color=always --icons --group-directories-first' alias ll='eza --icons --long --all --group-directories-first --git --header --time-style=relative' alias la='eza -a --color=always --group-directories-first' else if [[ "$OSTYPE" == darwin* ]]; then alias ls='ls -aFhG' alias ll='\ls -FlsG' alias la='\ls -AlhG' else alias ls='ls -aFh --color=always' alias ll='\ls -Fls --color=always' alias la='\ls -Alh --color=always' fi fi # Alias's for multiple directory listing commands if [[ "$OSTYPE" == darwin* ]]; then alias lx='\ls -lhG' # macOS: no -X flag, basic list alias lk='\ls -lSrhG' # sort by size alias lc='\ls -ltcrhG' # sort by change time alias lu='\ls -lturhG' # sort by access time alias lr='\ls -lRhG' # recursive ls alias lt='\ls -ltrhG' # sort by date alias lm='\ls -alhG | more' # pipe through 'more' alias lw='\ls -xAhG' # wide listing format alias labc='\ls -lapG' # alphabetical sort alias lf="\ls -lG | grep -v '^d'" # files only alias ldir="\ls -lG | grep '^d'" # directories only alias lla='\ls -AlG' # List and Hidden Files alias las='\ls -AG' # Hidden Files alias lls='\ls -lG' # List else alias lx='\ls -lXBh --color=always' # sort by extension alias lk='\ls -lSrh --color=always' # sort by size alias lc='\ls -ltcrh --color=always' # sort by change time alias lu='\ls -lturh --color=always' # sort by access time alias lr='\ls -lRh --color=always' # recursive ls alias lt='\ls -ltrh --color=always' # sort by date alias lm='\ls -alh --color=always | more' # pipe through 'more' alias lw='\ls -xAh --color=always' # wide listing format alias labc='\ls -lap --color=always' # alphabetical sort alias lf="\ls -l --color=always | grep -v '^d'" # files only alias ldir="\ls -l --color=always | grep '^d'" # directories only alias lla='\ls -Al --color=always' # List and Hidden Files alias las='\ls -A --color=always' # Hidden Files alias lls='\ls -l --color=always' # List fi # alias chmod commands alias mx='chmod a+x' alias 000='chmod -R 000' alias 644='chmod -R 644' alias 666='chmod -R 666' alias 755='chmod -R 755' alias 777='chmod -R 777' # Search command line history alias h="history | grep " # Search running processes alias p="ps aux | grep " alias topcpu="/bin/ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10" # Search files in the current folder alias f="find . | grep " # Count all files (recursively) in the current folder alias countfiles="for t in files links directories; do echo \`find . -type \${t:0:1} | wc -l\` \$t; done 2> /dev/null" # To see if a command is aliased, a file, or a built-in command alias checkcommand="type -t" # Show open ports if [[ "$OSTYPE" == darwin* ]]; then alias openports='lsof -i -P -n | grep LISTEN' else alias openports='netstat -nape --inet' fi # Alias's for safe and forced reboots alias rebootsafe='sudo shutdown -r now' if [[ "$OSTYPE" == darwin* ]]; then alias rebootforce='sudo shutdown -r now' else alias rebootforce='sudo shutdown -r -n now' fi alias shutdownsafe='sudo shutdown -h now' # Alias's to show disk space and space used in a folder alias diskspace="du -S | sort -n -r |more" alias folders='du -h -d 1' alias folderssort='find . -maxdepth 1 -type d -print0 | xargs -0 du -sk | sort -rn' if command -v tree &>/dev/null; then if tree --dirsfirst --help &>/dev/null 2>&1; then alias tree='tree -CAhF --dirsfirst' else alias tree='tree -CAhF' fi alias treed='tree -CAFd' elif command -v eza &>/dev/null; then alias tree='eza --tree --color=always --icons' fi alias mountedinfo='df -hT' # Alias's for archives alias mktar='tar -cvf' alias mkbz2='tar -cvjf' alias mkgz='tar -cvzf' alias untar='tar -xvf' alias unbz2='tar -xvjf' alias ungz='tar -xvzf' # Show all logs in /var/log alias logs="sudo find /var/log -type f -exec file {} \; | grep 'text' | cut -d' ' -f1 | sed -e's/:$//g' | grep -v '[0-9]$' | xargs tail -f" # alias to cleanup unused docker containers, images, networks, and volumes alias docker-clean=' \ docker container prune -f ; \ docker image prune -f ; \ docker network prune -f ; \ docker volume prune -f ' ####################################################### # SPECIAL FUNCTIONS ####################################################### # Extracts any archive(s) (if unp isn't installed) extract() { local archive for archive in "$@"; do if [ -f "$archive" ]; then case "$archive" in *.tar.bz2) tar xvjf "$archive" ;; *.tar.gz) tar xvzf "$archive" ;; *.bz2) bunzip2 "$archive" ;; *.rar) rar x "$archive" ;; *.gz) gunzip "$archive" ;; *.tar) tar xvf "$archive" ;; *.tbz2) tar xvjf "$archive" ;; *.tgz) tar xvzf "$archive" ;; *.zip) unzip "$archive" ;; *.Z) uncompress "$archive" ;; *.7z) 7z x "$archive" ;; *) echo "don't know how to extract '$archive'..." ;; esac else echo "'$archive' is not a valid file!" >&2 fi done } # Searches for text in all files in the current folder ftext() { grep -iIHrn --color=always "$1" . | less -r } # Copy and go to the directory cpg() { local src="$1" dest="$2" if [ -d "$dest" ]; then cp -r "$src" "$dest" && cd "$dest" else cp -r "$src" "$dest" fi } # Move and go to the directory mvg() { local src="$1" dest="$2" if [ -d "$dest" ]; then mv "$src" "$dest" && cd "$dest" else mv "$src" "$dest" fi } # Create and go to the directory mkdirg() { local dir_name="$1" mkdir -p "$dir_name" cd "$dir_name" } # Goes up a specified number of directories (i.e. up 4) up() { local d="" local limit=${1:-1} for ((i = 1; i <= limit; i++)); do d+="/.." done local target_path="" for ((i = 0; i < limit; i++)); do target_path="../${target_path}" done cd "${target_path}" } # Automatically do an ls after each cd, z, or zoxide cd() { local target_dir="$1" if [ -n "$target_dir" ]; then builtin cd "$target_dir" && ( set -- ls ) else builtin cd ~ && ( set -- ls ) fi } # Show the current distribution distribution() { local dtype="unknown" # Default to unknown # Use /etc/os-release for modern distro identification if [ -r /etc/os-release ]; then source /etc/os-release case "$ID" in fedora | rhel | centos) dtype="redhat" ;; sles | opensuse*) dtype="suse" ;; ubuntu | debian) dtype="debian" ;; gentoo) dtype="gentoo" ;; arch | manjaro) dtype="arch" ;; slackware) dtype="slackware" ;; *) # Check ID_LIKE only if dtype is still unknown if [ -n "$ID_LIKE" ]; then case "$ID_LIKE" in *fedora* | *rhel* | *centos*) dtype="redhat" ;; *sles* | *opensuse*) dtype="suse" ;; *ubuntu* | *debian*) dtype="debian" ;; *gentoo*) dtype="gentoo" ;; *arch*) dtype="arch" ;; *slackware*) dtype="slackware" ;; esac fi ;; esac fi echo "$dtype" } # Show the current version of the operating system ver() { local dtype dtype=$(distribution) case "$dtype" in "redhat") if [ -s /etc/redhat-release ]; then cat /etc/redhat-release else cat /etc/issue fi uname -a ;; "suse") if [ -s /etc/SuSE-release ]; then cat /etc/SuSE-release elif [ -s /etc/os-release ]; then cat /etc/os-release else cat /etc/issue fi ;; "debian") lsb_release -a ;; "gentoo") cat /etc/gentoo-release ;; "arch") cat /etc/os-release ;; "slackware") cat /etc/slackware-version ;; *) if [ -s /etc/issue ]; then cat /etc/issue else echo "Error: Unknown distribution" >&2 return 1 fi ;; esac } # Automatically install the needed support files for this .bashrc file install_bashrc_support() { local dtype dtype=$(distribution) case "$dtype" in "redhat") if command -v dnf &>/dev/null; then sudo dnf install -y --skip-broken --refresh --skip-unavailable tree zoxide fzf bash-completion fastfetch bat ripgrep alacritty else sudo yum install -y -q tree zoxide fzf bash-completion fastfetch eza bat ripgrep alacritty fi ;; "suse") sudo zypper install -n --auto-agree-with-licenses tree zoxide fzf bash-completion fastfetch eza bat ripgrep alacritty ;; "debian") sudo apt-get update sudo apt-get install tree zoxide fzf bash-completion eza bat ripgrep alacritty local FASTFETCH_URL FASTFETCH_URL=$(curl -s https://api.github.com/repos/fastfetch-cli/fastfetch/releases/latest | grep "browser_download_url.*linux-amd64.deb" | cut -d '"' -f 4) if [ -n "$FASTFETCH_URL" ]; then curl -sL "$FASTFETCH_URL" -o /tmp/fastfetch_latest_amd64.deb sudo apt-get install /tmp/fastfetch_latest_amd64.deb rm /tmp/fastfetch_latest_amd64.deb else echo "Warning: Could not find fastfetch .deb URL." >&2 fi ;; "arch") if command -v yay &>/dev/null; then yay -S --noconfirm --needed zoxide fzf bash-completion fastfetch starship eza bat ripgrep ttf-firacode-nerd trash-cli fd yazi tlrc-bin alacritty elif command -v pacman &>/dev/null; then sudo pacman -S --noconfirm --needed zoxide fzf bash-completion fastfetch starship eza bat ripgrep ttf-firacode-nerd trash-cli fd yazi alacritty else echo "Neither yay nor pacman found. Cannot install." >&2 fi ;; "slackware") echo "No install support for Slackware" >&2 ;; *) echo "Unknown distribution. Cannot install." >&2 ;; esac } install_i3_support() { local dtype dtype=$(distribution) case "$dtype" in "debian" | "suse") echo "i3 support installation not yet implemented for $dtype-based systems." >&2 ;; "redhat") if command -v dnf &>/dev/null; then sudo dnf install -y --skip-broken --refresh --skip-unavailable tree zoxide fzf bash-completion fastfetch bat ripgrep alacritty else sudo yum install -y -q tree zoxide fzf bash-completion fastfetch eza bat ripgrep alacritty fi ;; "arch") if command -v yay &>/dev/null; then yay -S --needed --noconfirm picom feh i3-auto-tiling rofi flameshot xclip alacritty elif command -v pacman &>/dev/null; then sudo pacman -S --needed --noconfirm picom feh rofi flameshot xclip alacritty echo "⚠️ 'i3-auto-tiling' is not in official repos; skipping." >&2 else echo "❌ Neither yay nor pacman found. Cannot install." >&2 fi ;; "slackware") echo "Slackware is not supported for automated i3 setup." >&2 ;; *) echo "Unknown distribution: $dtype. Cannot install i3 support." >&2 ;; esac } if command -v bat &>/dev/null; then alias cat='bat' elif command -v batcat &>/dev/null; then alias cat='batcat' fi # IP address lookup whatsmyip() { echo -n "Internal IP: " if command -v ip >/dev/null; then ip -4 addr show scope global | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1 elif command -v ifconfig >/dev/null; then ifconfig | awk '/inet / && $2 != "127.0.0.1" {print $2}' | head -n 1 else echo "N/A" fi echo -n "External IPv4: " curl -s --connect-timeout 5 https://api.ipify.org || echo "N/A" echo -n -e "\nExternal IPv6: " curl -s --connect-timeout 5 https://api6.ipify.org || echo "N/A" } alias myip="whatsmyip" ####################################################### # Set the ultimate amazing command prompt ####################################################### if [[ $- == *i* ]]; then if command -v zoxide >/dev/null; then bind '"\C-f":"zi\n"' fi bind '"\e[A": history-search-backward' bind '"\e[B": history-search-forward' bind '"\C-h": backward-kill-word' fi ####################################################### # EXTERNAL TOOL INITIALIZATION ####################################################### if command -v starship &>/dev/null; then eval "$(starship init bash)" fi if command -v zoxide &>/dev/null; then eval "$(zoxide init bash)" fi ####################################################### # YAZI ####################################################### if command -v yazi &>/dev/null; then function y() { local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd yazi "$@" --cwd-file="$tmp" IFS= read -r -d '' cwd <"$tmp" [ -n "$cwd" ] && [ "$cwd" != "$PWD" ] && builtin cd -- "$cwd" rm -f -- "$tmp" } fi ####################################################### # FZF integration ####################################################### # Enables the following keybindings (if available): # CTRL-T - Fuzzy find files # CTRL-R - Fuzzy reverse search through history # ALT-C - Fuzzy cd into subdirectories if command -v fzf >/dev/null; then if fzf --bash >/dev/null 2>&1; then eval "$(fzf --bash)" elif [[ -f ~/.fzf.bash ]]; then source ~/.fzf.bash elif [[ -f /usr/share/fzf/key-bindings.bash ]]; then source /usr/share/fzf/key-bindings.bash source /usr/share/fzf/completion.bash 2>/dev/null fi fi ## replace find with fd if available for fzf # fzf and fd integration if command -v fzf &>/dev/null && command -v fd &>/dev/null; then export FZF_DEFAULT_COMMAND="fd --type f --hidden --exclude .git --color=never" export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" export FZF_ALT_C_COMMAND="fd --type d --hidden --exclude .git --color=never" fi ####################################################### # STARTUP ####################################################### if command -v fastfetch &>/dev/null; then fastfetch fi # Add NVM and its binaries to Path if available export NVM_DIR="$HOME/.config/nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # Add Rust's cargo bin directory to PATH if it exists [ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" [ -d "$HOME/flutter/bin" ] && export PATH="$HOME/flutter/bin:$PATH" ####################################################### # GO SETUP ####################################################### GO_FOUND="" if command -v go >/dev/null 2>&1; then GO_FOUND="yes" elif [ -x "$HOME/go/bin/go" ]; then export PATH="$HOME/go/bin:$PATH" GO_FOUND="yes" elif [ -x "/usr/local/go/bin/go" ]; then export PATH="/usr/local/go/bin:$PATH" GO_FOUND="yes" fi if [ "$GO_FOUND" = "yes" ]; then export GOPATH="${GOPATH:-$HOME/go}" [ -d "$GOPATH/bin" ] && export PATH="$PATH:$GOPATH/bin" fi # Set ANDROID_HOME if the SDK directory exists if [ -d "$HOME/Android/Sdk" ]; then export ANDROID_HOME="$HOME/Android/Sdk" # Add platform-tools and cmdline-tools to PATH if they exist if [ -d "$ANDROID_HOME/platform-tools" ]; then export PATH="$ANDROID_HOME/platform-tools:$PATH" fi if [ -d "$ANDROID_HOME/cmdline-tools/latest/bin" ]; then export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$PATH" fi fi