# Shell Functions # tar/gzip a directory # I use this before 'rm -rf'ing a directory I think is useless # if nothing breaks after a predetermined amount of time, then the tar file is safe to delete tardir() { #ensure $1 is a directory if [ ! -d "${1}" ]; then echo "$1 is not a directory. Aborting." return 1 fi #strip trailing slash target="${1%/}" current_date=$(date +%Y-%m-%d) echo "Dir size: $(du -hs ${target})" tar czf "${target}.${current_date}".tar.gz "${target}" echo "Archive size: $(du -hs ${target}.${current_date}.tar.gz)" } # Replacement for 'for i in $(ls); do du -hs $i; done' that handles spaces function dudir() { if ! (($#)); then dir=$(pwd) else dir="${1}" fi # redefine $IFS o=$IFS IFS=$(echo -en "\n\b") for i in $(ls "${dir}"); do du -hs "${i}" done # reset $IFS IFS=$o } # HAHA! Weather in the terminal weather() { if [ $(command -v curl) ]; then if ! (($#)); then curl wttr.in/44113 else curl wttr.in/$1 fi else echo "curl not installed. Aborting." fi } # Replaces "ps aux | grep " with "psaux ". Shorter to type, more informational and doesn't include the command itself in the output. psaux () { pgrep -f "$@" | xargs ps -fp 2>/dev/null; } # mail a file email() { if ! command -v mail &> /dev/null; then echo "Error: 'mail' command not found. Please ensure a Mail Transfer Agent (MTA) is installed and configured." return 1 elif ! (($#)); then echo "USAGE: email {filename} {email-address}" return 1 else efile=${1} eaddr=${2} echo "See Attached" | mail -s "File: ${efile}" -a ${efile} ${2} fi } # git testmerge testmerge() { if [ -z "$1" ]; then echo "Usage: testmerge " echo " (e.g., 'testmerge feature/my-new-feature')" return 1 fi echo "Attempting a dry-run merge of '$1' into the current branch..." # Perform the merge without committing, and force a merge commit even if fast-forward is possible git merge --no-commit --no-ff "$1" # Check the exit status of the merge command if [ $? -eq 0 ]; then echo "" echo "--- Proposed Changes (git diff --cached) ---" git diff --cached echo "--------------------------------------------" echo "" echo "Merge state is now active. You can inspect the changes above." echo "To finalize the merge, run: 'git commit'" echo "To abort the merge and return to the previous state, run: 'git merge --abort'" else echo "" echo "Merge encountered issues (e.g., conflicts). Please resolve them manually." echo "To abort the merge and return to the previous state, run: 'git merge --abort'" fi } # Quickly display local IP addresses myip() { echo "IPv4 Addresses:" ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' echo "" echo "IPv6 Addresses:" ip -6 addr show | grep -oP '(?<=inet6\s)[0-9a-fA-F:]+' | grep -v '::1' } # Universal archive extractor extract() { if [ -z "$1" ]; then echo "Usage: extract " return 1 fi if [ -f "$1" ]; then case "$1" in *.tar.bz2) tar xvjf "$1" ;; *.tar.gz) tar xvzf "$1" ;; *.bz2) bunzip2 "$1" ;; *.rar) unrar x "$1" ;; *.gz) gunzip "$1" ;; *.tar) tar xvf "$1" ;; *.tbz2) tar xvjf "$1" ;; *.tgz) tar xvzf "$1" ;; *.zip) unzip "$1" ;; *.Z) uncompress "$1" ;; *.7z) 7za x "$1" ;; *.deb) ar x "$1" ;; *.tar.xz) tar xvJf "$1" ;; *.tar.zst) tar --use-compress-program=zstd -xvf "$1" ;; *.xz) unxz "$1" ;; *.zst) zstd -d "$1" ;; *) echo "'$1' cannot be extracted via extract()" ;; esac else echo "'$1' is not a valid file" fi } # Make a directory and change into it mkcd() { mkdir -p "$1" && cd "$1" } # Docker cleanup: remove stopped containers, dangling images, and unused volumes docker_cleanup() { echo "Removing stopped containers..." docker rm $(docker ps -aq) 2>/dev/null || echo "No stopped containers to remove." echo "Removing dangling images..." docker rmi $(docker images -f "dangling=true" -q) 2>/dev/null || echo "No dangling images to remove." echo "Removing unused volumes..." docker volume rm $(docker volume ls -f "dangling=true" -q) 2>/dev/null || echo "No unused volumes to remove." echo "Docker cleanup complete." }