#!/bin/bash - not strictly necessary, but helps nano with syntax highlighting. __prompt_git_status() { # Generate a git branch/status prompt. # Based on git-prompt.sh by Shawn O. Pearce . # Arguments: # $1 The printf format string for the prompt. Must include %s. # Environment variables: # GIT_PROMPT_SHOW_TYPE=1 Show type of repository (Bare, Shallow). # GIT_PROMPT_SHOW_UPSTREAM=1 Show status of this repository compaired to upstream: # ?? - No upstream set. # == - Working tree is equal to upstream. # <> - Divergent from upstream. # >> or >x - Working tree is ahead of upstream (x = commits ahead when used with next option). # << or 5 * # Returns: 0 = Produced a prompt successfully. # 1 = An error occured. local BRANCH COUNT GIT_PROMPT GIT_PROMPT_MARKER_SET GIT_REPO_INFO IFS=$'\n' # Bail out if there's no format argument given, or it doesn't contain %s (( $# != 1 )) || [[ "$1" != *%s* ]] && return 1 # Get some repository information. # shellcheck disable=SC2207 GIT_REPO_INFO=( $( git rev-parse --is-bare-repository --is-shallow-repository --is-inside-git-dir --is-inside-work-tree 2>/dev/null) ) || return 1 # Generate the prompt. if [[ "${GIT_REPO_INFO[2]}" == "true" ]]; then # In the git directory, use a special branch marker. GIT_PROMPT+="!GIT_DIR!" elif [[ "${GIT_REPO_INFO[3]}" == "true" ]]; then # In the working directory, generate the prompt. # Add type markers. [[ -n "$GIT_PROMPT_SHOW_TYPE" ]] && { if [[ "${GIT_REPO_INFO[0]}" == "true" ]]; then GIT_PROMPT+="B:" elif [[ "${GIT_REPO_INFO[1]}" == "true" ]]; then GIT_PROMPT+="S:" fi } # Add the branch or a no commits marker. BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)" if [[ "$BRANCH" == "HEAD" ]]; then GIT_PROMPT+="?NO COMMITS?" # Output the prompt and escape early. # shellcheck disable=SC2059 printf -- "$1" "$GIT_PROMPT" return 0 else GIT_PROMPT+="$BRANCH" fi # Add upstream status. [[ -n "$GIT_PROMPT_SHOW_UPSTREAM" ]] || [[ -n "$GIT_PROMPT_SHOW_UPSTREAM_EXTENDED" ]] && { COUNT="$(git rev-list --count --left-right "${BRANCH:+refs/prefetch/remotes/origin/}${BRANCH:-@{upstream\}}...HEAD" 2>/dev/null | tr '[:blank:]' ' ')" case "$COUNT" in "") # No upstream. GIT_PROMPT+=" ??" ;; "0 0") # Equal to upstream. GIT_PROMPT+=" ==" ;; "0 "*) # Ahead of upstream. GIT_PROMPT+=" >" if [[ -n "$GIT_PROMPT_SHOW_UPSTREAM_EXTENDED" ]]; then # Show the number of the difference. GIT_PROMPT+="${COUNT#0 }" else GIT_PROMPT+=">" fi ;; *" 0") # Behind upstream. GIT_PROMPT+=" <" if [[ -n "$GIT_PROMPT_SHOW_UPSTREAM_EXTENDED" ]]; then # Show the number of the difference. GIT_PROMPT+="${COUNT% 0}" else GIT_PROMPT+="<" fi ;; *) # Divergent from upstream. GIT_PROMPT+=" <>" ;; esac } # Add a marker if directory is ignored, there's unstaged files, uncommitted changes, untracked files or a stash. [[ -n "$GIT_PROMPT_SHOW_IGNORED" ]] && git check-ignore . >/dev/null 2>&1 && { GIT_PROMPT+=" !" GIT_PROMPT_MARKER_SET=1 } [[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_UNSTAGED" ]] && { timeout --signal=KILL 2s git ls-files --modified --exclude-standard --directory --error-unmatch -- ':/*' >/dev/null 2>&1 ERR=$? if (( ERR == 124 )) || (( ERR == 137 )); then GIT_PROMPT+=" _" GIT_PROMPT_MARKER_SET=1 elif (( ERR == 0 )); then GIT_PROMPT+=" *" GIT_PROMPT_MARKER_SET=1 fi } [[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_UNCOMMITTED" ]] && ! git diff --name-only --cached --exit-code >/dev/null 2>&1 && { GIT_PROMPT+=" &" GIT_PROMPT_MARKER_SET=1 } [[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_UNTRACKED" ]] && { timeout --signal=KILL 2s git ls-files git ls-files --others --exclude-standard --directory --error-unmatch -- ':/*' >/dev/null 2>&1 ERR=$? if (( ERR == 124 )) || (( ERR == 137 )); then GIT_PROMPT+=" _" GIT_PROMPT_MARKER_SET=1 elif (( ERR == 0 )); then GIT_PROMPT+=" +" GIT_PROMPT_MARKER_SET=1 fi } [[ -z "$GIT_PROMPT_MARKER_SET" ]] && [[ -n "$GIT_PROMPT_SHOW_STASH" ]] && git rev-parse --verify --quiet refs/stash >/dev/null && { GIT_PROMPT+=" $" GIT_PROMPT_MARKER_SET=1 } fi # Output the prompt. # shellcheck disable=SC2059 printf -- "$1" "$GIT_PROMPT" return 0 } __prompt_user_colour() { # Determine the colour of the username in the prompt. if [[ "$LOGNAME" == "root" ]]; then printf "%s" "1;31m" # Bright Red. elif [[ "$LOGNAME" == "tadgy" ]]; then printf "%s" "1;32m" # Bright Green. else printf "%s" "1;36m" # Bright Cyan. fi return 0 } __git_prompt_command() { # Perform git actions. # Environment variables: # GIT_DISABLE_PROMPT_PREFETCH=1 Disable automatic 'prefetch' of upstream refs. # This can also be disabled on a per repository basis using: # git config ---local -replace-all --type bool script.DisablePromptPrefetch true # Returns: 0 = Tasks completed successfully. # 1 = An error occured. local GIT_REPO_INFO LC_ALL="C" NOW REPO_TIMESTAMP TIMESTAMP_VAR # shellcheck disable=SC2207 GIT_REPO_INFO=( $( git rev-parse --is-inside-work-tree --show-toplevel 2>/dev/null) ) || return 1 # Only process if in a work directory. [[ "${GIT_REPO_INFO[0]}" == "true" ]] && { # Run prefetch tasks if not disabled. [[ -z "$GIT_DISABLE_PROMPT_PREFETCH" ]] && [[ "$(git config --local --get --type bool script.DisablePromptPrefetch 2>/dev/null)" != "true" ]] && { git maintenance run --task=prefetch 2>/dev/null || { printf "\\033[1;31m%s\\033[0m\\n" "Git maintenance 'prefetch' task failed." >&2 return 1 } } # The time now. if [[ "$PLATFORM" == "Linux" ]]; then NOW="$(date +'%s%3N')" elif [[ "$PLATFORM" == "Darwin" ]]; then NOW="$(perl -e 'use Time::HiRes; printf "%.3f", Time::HiRes::time();')" NOW="${NOW/.}" fi # Determine the timestamp variable name depending on bash version. if (( BASH_VERSINFO[0] >= 4 )); then TIMESTAMP_VAR="GIT_REPO_TIMESTAMP[${GIT_REPO_INFO[1]//[^[:alnum:]]/_}]" else # This is going to pollute the environment, but Darwin is a PITA. TIMESTAMP_VAR="GIT_REPO_TIMESTAMP_${GIT_REPO_INFO[1]//[^[:alnum:]]/_}" fi if [[ -n "${!TIMESTAMP_VAR}" ]]; then # Monitor the git repo. REPO_TIMESTAMP="$(git config --local --get --type int script.AutoMergeLast)" (( ${!TIMESTAMP_VAR:-0} < REPO_TIMESTAMP )) && { # Display message depending on status. if [[ "$(git config --local --get --type bool script.AutoMergeSuccess)" == "true" ]]; then printf "\\033[1;32m%s" "Git auto-merge succeeded for this repo." if [[ "${GIT_REPO_INFO[1]}" == "$HOME" ]]; then printf " %s\\033[0m\\n" "Re-source .bash* files." else printf "\\033[0m\\n" fi # Update the timestamp in the environment. declare -g "$TIMESTAMP_VAR"="$NOW" else printf "\\033[1;31m%s\\033[0m\\n" "Git auto-merge failed for this repo - correct manually." >&2 fi } else # Just set the timestamp in the environment. declare -g "$TIMESTAMP_VAR"="$NOW" fi } return 0 } __nanorc_prompt_command() { # Dynamically handle .nanorc file versions. hash nano >/dev/null 2>&1 && { # shellcheck disable=SC2155 local NANO_VER="$(command nano --version | awk '/version/ { print $4 }' | cut -d. -f1)" # Darwin specifc .nanorc version. [[ "$PLATFORM" == "Darwin" ]] && NANO_VER="darwin" if [[ -f "$HOME/.nanorc-$NANO_VER" ]]; then if (( NANO_VER <= 4 )); then ( cd "$HOME" && ln -sf ".nanorc-$NANO_VER" ".nanorc" ) else # shellcheck disable=SC2139 alias nano="nano -f \"$HOME/.nanorc-$NANO_VER\"" fi else if (( NANO_VER <= 4 )); then [[ -L "$HOME/.nanorc" ]] && rm -f "$HOME/.nanorc" else unalias nano 2>/dev/null fi printf "\\033[1;31m%s\\033[0m\\n" "No .nanorc for version '$NANO_VER'." >&2 fi } return 0 } __ssh_agent_prompt_command() { # If necessary, find and activate a new ssh agent socket before each prompt is displayed. # Returns: 0 = All is good. # 1 = An error occured. local ERR if [[ -z "$SSH_AUTH_SOCK" ]]; then ERR=2 else ssh-add -l >/dev/null 2>&1 ERR=$? fi (( ERR == 2 )) && { # Read alternative sockets from ~/.ssh/agents. __read_ssh_agents || { unset SSH_AUTH_SOCK return 1 } # Find a new socket to use. if __find_ssh_agent_sock; then printf "\\033[1;33m%s\\033[0m\\n" "Connected to existing ssh-agent socket." sleep 0.5 else # Start a new agent. eval "$(ssh-agent -s 2>/dev/null | grep -v 'echo'; printf "%s" "ERR=${PIPESTATUS[0]}")" (( ERR > 0 )) && { printf "\\033[1;31m%s\\033[0m\\n" "Failed to start new ssh-agent - continuing with no agent." sleep 0.5 return 1 } printf "\\033[1;32m%s\\033[0m\\n" "Started new ssh-agent." __write_ssh_agents sleep 0.5 fi } return 0 } __find_ssh_agent_sock() { # Find an *active* ssh agent socket. # Returns: 0 = Found an active socket. # 1 = Did not find a viable socket. local I # Search the SSH_AUTH_SOCKS array for a viable socket. for ((I = 0; I < ${#SSH_AUTH_SOCKS[@]}; I++)); do [[ "${SSH_AUTH_SOCKS[$I]}" =~ ^[[:blank:]]*$ ]] && continue SSH_AUTH_SOCK="${SSH_AUTH_SOCKS[$I]}" ssh-add -l >/dev/null 2>&1 (( $? <= 1 )) && { export SSH_AUTH_SOCK="${SSH_AUTH_SOCKS[$I]}" return 0 } unset SSH_AUTH_SOCK done return 1 } __read_ssh_agents() { # Read all the known ssh agent sockets into an array. # Returns: 0 = Processed and read the agents file without issue. # 1 = Error processing/reading the agents file. local ERR I SOCK [[ ! -e "$HOME/.ssh/agents" ]] && touch "$HOME/.ssh/agents" # Lock the ~/.ssh/agents file. if [[ "$PLATFORM" == "Linux" ]]; then # Linux has 'flock', thankfully. exec 9<"$HOME/.ssh/agents" && flock -E 10 -e -w 0.5 9 ERR=$? if (( ERR == 10 )); then printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2 return 1 elif (( ERR > 0 )); then printf "\\033[1;31m%s\\033[0m\\n" "Flock usage error." >&2 return 1 fi # Make note of the mtime for use in write_ssh_agents. SSH_AGENTS_MTIME="$(stat --format=%.9Y "$HOME/.ssh/agents")" elif [[ "$PLATFORM" == "Darwin" ]]; then # Do locking the sucky way on macOS. for ((I = 0; I <= 5; I++)); do if shlock -p "$$" -f "$HOME/.ssh/agents.lock"; then exec 9<"$HOME/.ssh/agents" # Make note of the mtime for use in write_ssh_agents. SSH_AGENTS_MTIME="$(stat -f %Fm "$HOME/.ssh/agents")" ERR=0 break else ERR=1 sleep 0.1 fi done (( ERR != 0 )) && { printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2 return 1 } else printf "\\033[1;31m%s\\033[0m\\n" "File locking unsupported on '$PLATFORM'." >&2 return 1 fi # Read the socket list (bash v2+ compliant) while read -u 9 -r SOCK; do [[ -n "$SOCK" ]] && SSH_AUTH_SOCKS+=("$SOCK") done ERR=$? # Close the file descriptor (which on Linux releases the flock too). exec 9<&- # On Darwin, release the lock on the file. rm -f "$HOME/.ssh/agents.lock" # Remove the . in the mtime. SSH_AGENTS_MTIME="${SSH_AGENTS_MTIME/\.}" # Error out if the data couldn't be read. (( ERR != 0 )) && { printf "\\033[1;31m%s\\033[0m\\n" "Failed to read ssh-agent socket list." >&2 unset SSH_AUTH_SOCKS SSH_AGENTS_MTIME return 1 } return 0 } __write_ssh_agents() { # Write all unique ssh agent sockets into the ~/.ssh/agents file. # Returns: 0 = Processed and wrote the agents file without issue. # 1 = Error processing/writing the agents file. # 2 = The SSH_AUTH_SOCKS array may be out of date as the agents file'a mtime has changed. local ERR I J MTIME SOCKS # Add the current agent socket to the sockets array. SSH_AUTH_SOCKS=("$SSH_AUTH_SOCK" "${SSH_AUTH_SOCKS[@]}") # Remove any duplicates from SSH_AUTH_SOCKS. for ((I = 0; I < ${#SSH_AUTH_SOCKS[@]}; I++)); do [[ -z "${SSH_AUTH_SOCKS[$I]}" ]] && continue for ((J = 0; J < ${#SOCKS[@]}; J++)); do [[ "${SSH_AUTH_SOCKS[$I]}" == "${SOCKS[$J]}" ]] && continue 2 done # Only add the socket if it's still viable. SSH_AUTH_SOCK="${SSH_AUTH_SOCKS[$I]}" ssh-add -l >/dev/null 2>&1 (( $? <= 1 )) && SOCKS+=("${SSH_AUTH_SOCKS[$I]}") done # Lock the ~/.ssh/agents file. if [[ "$PLATFORM" == "Linux" ]]; then # Make sure SSH_AUTH_SOCKS has the most up to date data. MTIME="$(stat --format=%.9Y "$HOME/.ssh/agents")" (( ${MTIME/\.} > SSH_AGENTS_MTIME )) && return 2 # Lock the agents file. exec 9<"$HOME/.ssh/agents" && flock -E 10 -e -w 0.5 9 ERR=$? if (( ERR == 10 )); then printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2 return 1 elif (( ERR > 0 )); then printf "\\033[1;31m%s\\033[0m\\n" "Flock usage error." >&2 return 1 fi elif [[ "$(uname -s)" == "Darwin" ]]; then # Make sure SSH_AUTH_SOCKS has the most up to date data. MTIME="$(stat -f %Fm "$HOME/.ssh/agents")" (( ${MTIME/\.} > SSH_AGENTS_MTIME )) && return 2 # Do locking the sucky way on OSX. for ((I = 0; I <= 5; I++)); do if shlock -p "$$" -f "$HOME/.ssh/agents.lock"; then exec 9<"$HOME/.ssh/agents" ERR=0 break else ERR=1 sleep 0.1 fi done (( ERR != 0 )) && { printf "\\033[1;31m%s\\033[0m\\n" "Failed to obtain lock on ~/.ssh/agents." >&2 return 1 } else printf "\\033[1;31m%s\\033[0m\\n" "File locking unsupported on '$PLATFORM'." >&2 return 1 fi # Write the cleaned array to disk. ERR=-1 [[ -n "${SOCKS[*]}" ]] && { printf "%s\\n" "${SOCKS[@]}" >"$HOME/.ssh/agents" 2>/dev/null; ERR=$?; } # Release locks. exec 9<&- rm -f "$HOME/.ssh/agents.lock" # Error out if the data couldn't be written. if (( ERR == -1 )); then rm -f "$HOME/.ssh/agents" 2>/dev/null elif (( ERR >= 1 )); then rm -f "$HOME/.ssh/agents" 2>/dev/null printf "\\033[1;31m%s\\033[0m\\n" "Failed to write ssh-agent socket list." >&2 return 1 fi return 0 } imagebin() { # Throw an image file into an imagebin. [[ -z "$1" ]] || [[ ! -e "$1" ]] && { printf "%s: %s\\n" "Usage" "${FUNCNAME[0]} " >&2 return 1 } curl -F file="@$1" https://imagebin.ca/upload.php | grep '^url:' | cut -d: -f2- } # Determine the platform being logged into. PLATFORM="$(uname -s)" # Make bash a little more pleasent - these are valid for all versions. shopt -s cdspell checkhash checkwinsize cmdhist histappend no_empty_cmd_completion # Exit the shell on a Ctl+D. IGNOREEOF=0 # History control. HISTCONTROL="ignoredups" HISTFILE="$HOME/.bash_history-${HOSTNAME%%.*}" HISTFILESIZE=1000000 HISTIGNORE="bg:bg *:fg:fg *:jobs:exit:clear:history" HISTSIZE=1000000 HISTTIMEFORMAT="%d/%m/%y %H:%M:%S " history -a history -r # The commands to execute before the prompt is displayed. PROMPT_COMMAND="__nanorc_prompt_command; __ssh_agent_prompt_command; __git_prompt_command" # Git prompt options. GIT_PROMPT_SHOW_TYPE=1 GIT_PROMPT_SHOW_UPSTREAM=1 GIT_PROMPT_SHOW_UPSTREAM_EXTENDED=1 GIT_PROMPT_SHOW_IGNORED=1 GIT_PROMPT_SHOW_UNSTAGED=1 GIT_PROMPT_SHOW_UNCOMMITTED=1 GIT_PROMPT_SHOW_UNTRACKED=1 GIT_PROMPT_SHOW_STASH=1 # Version specific set up. if (( BASH_VERSINFO[0] >= 4 )); then # Add to the shopts. shopt -s checkjobs dirspell # Trim the path in the prompt. PROMPT_DIRTRIM=2 # Coloured username + host + directory: PS1='[\[\033[$(__prompt_user_colour)\]\u\[\033[0m\]@\[\033[1;33m\]\h\[\033[0m\]] \[\033[1;34m\]\w\[\033[0m\]$(__prompt_git_status "\[\\033[1;35m\] (%s)\[\\033[0m\]") ->' else # Set the prompts. # Coloured username + host + directory: # shellcheck disable=SC2154 PS1='[\[\033[$(__prompt_user_colour)\]\u\[\033[0m\]@\[\033[1;33m\]\h\[\033[0m\]] \[\033[1;34m\]$(printf "%s" "${PWD/#$HOME/~}" | awk -F/ '\''{if (NF>3) {printf ".../" $(NF-1) "/" $NF} else {printf $0}}'\'')\[\033[0m\]$(__prompt_git_status "\[\\033[1;35m\] (%s)\[\\033[0m\]") ->' fi # Set the debugger prompt. # shellcheck disable=SC2155 export PS4='+(\[\033[1;33m\]$?\[\033[0m\]) \[\033[1;34m\]${BASH_SOURCE##*/}\[\033[0m\]${FUNCNAME[0]:+(\[\033[1;32m\]${FUNCNAME[0]}\[\033[0m\])}:\[\033[1;31m\]$LINENO\[\033[0m\]: ' # Common aliases. hash bc >/dev/null 2>&1 && alias bc='bc -lq' hash grep >/dev/null 2>&1 && { alias egrep='grep -E --color=auto' alias fgrep='grep -F --color=auto' alias grep='grep --color=auto' } # Auto start the ssh agent and add keys for scp/sftp/ssh. __ssh_agent_prompt_command hash scp ssh ssh-add >/dev/null 2>&1 && alias scp='_EXEC=scp ssh' hash sftp ssh ssh-add >/dev/null 2>&1 && alias sftp='_EXEC=sftp ssh' hash ssh ssh-add >/dev/null 2>&1 && ssh() { local ERR if [[ -z "$SSH_AUTH_SOCK" ]]; then ERR=2 else ssh-add -l >/dev/null 2>&1 ERR=$? fi if (( ERR == 1 )); then ssh-add elif (( ERR == 2 )); then __ssh_agent_prompt_command ssh-add fi command "${_EXEC:-${FUNCNAME[0]}}" "$@" } # Handle the ~/.gitconfig link. if [[ -e "$HOME/.gitconfig-$USER@$HOSTNAME" ]]; then FILENAME=".gitconfig-$USER@$HOSTNAME" elif [[ -e "$HOME/.gitconfig-$USER@*.${HOSTNAME#*.}" ]]; then FILENAME=".gitconfig-$USER@*.${HOSTNAME#*.}" elif [[ -e "$HOME/.gitconfig-$USER@*" ]]; then FILENAME=".gitconfig-$USER@*" elif [[ -e "$HOME/.gitconfig-*@$HOSTNAME" ]]; then FILENAME=".gitconfig-*@$HOSTNAME" elif [[ -e "$HOME/.gitconfig-*.${HOSTNAME#*.}" ]]; then FILENAME=".gitconfig-*.${HOSTNAME#*.}" elif [[ -e "$HOME/.gitconfig-default" ]]; then FILENAME=".gitconfig-default" else (cd "$HOME" && [[ -L ".gitconfig" ]] && rm -f ".gitconfig") printf "%s: %s\\n" "${BASH_SOURCE##*/}" "failed to update .gitconfig symlink" >&2 fi [[ -n "$FILENAME" ]] && (cd "$HOME" && ln -sf "$FILENAME" ".gitconfig") unset FILENAME # Platform specific set up. if [[ "$PLATFORM" = "Linux" ]]; then # Linux specific functions. hash ps grep >/dev/null 2>&1 && psgrep() { if [[ -n "$1" ]]; then # shellcheck disable=SC2009 ps -auwwx | grep -E --color=always -- "(.*RSS.*|$1)" | grep -F -v '(.*RSS.*|' else printf "%s: %s\\n" "Usage" "${FUNCNAME[0]} " >&2 return 1 fi } # Linux specific aliases. hash diff >/dev/null 2>&1 && alias diff='diff --color=auto -u' hash ftpwho >/dev/null 2>&1 && alias ftpwho='ftpwho -v' hash gpg2 >/dev/null 2>&1 && alias gpg='command gpg2' && alias gpg2='gpg2 --pinentry-mode=loopback' hash iftop >/dev/null 2>&1 && alias iftop='TERM=vt100 iftop' hash iotop >/dev/null 2>&1 && alias iotop='TERM=linux iotop' hash ip >/dev/null 2>&1 && alias ip='ip -color=auto' hash last less >/dev/null 2>&1 && alias laston='last -a | less' hash ls >/dev/null 2>&1 && alias ls='ls -bFv --color=auto' hash minicom >/dev/null 2>&1 && alias minicom='minicom -m -c on' hash mkpasswd >/dev/null 2>&1 && alias mkpasswd='mkpasswd -m sha512crypt' hash mkpasswd >/dev/null 2>&1 && alias pwgen='mkpasswd -m sha512crypt' hash nc >/dev/null 2>&1 && alias pastebin='nc termbin.com 9999' hash pinfo >/dev/null 2>&1 && alias info='pinfo' hash ping >/dev/null 2>&1 && alias ping='ping -b' elif [[ "$PLATFORM" = "Darwin" ]]; then # Darwin specific aliases (some dependant on macports) [[ ! -e "/opt/local/libexec/gnubin/df" ]] && alias df='df -kP' # shellcheck disable=SC2015 [[ ! -e "/opt/local/libexec/gnubin//diff" ]] && alias diff='diff -u' || alias diff='diff --color=auto -u' hash last less >/dev/null 2>&1 && alias laston='last | less' # shellcheck disable=SC2015 [[ ! -e "/opt/local/libexec/gnubin/ls" ]] && alias ls='ls -bFGO' || alias ls='ls -bFv --color=auto' [[ -e "/opt/local/libexec/gnubin/nc" ]] && alias pastebin='nc termbin.com 9999' [[ -e "/opt/local/bin/pinfo" ]] && alias info='pinfo' hash top >/dev/null 2>&1 && alias top='top -o cpu -S' else printf "%s: %s\\n" "${BASH_SOURCE##*/}" "unsupported platform: $PLATFORM" >&2 fi