Originally published March 18, 2021 @ 8:20 pm

Some of the useful (more or less) aliases and functions for the .bashrc file to make your life a little easier and delay the onset of carpal tunnel syndrome.

Things to remove from .bashrc

Few things annoy me more than these three default command aliases. Removing them is one of the first things I do after installing a new OS:

alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'

Command History

Adding a timestamp to your shell command history is a must. This will help you figure out not just what stupid mistake you made, but also when you made it.

export HISTTIMEFORMAT='| %F %T | '
export HISTSIZE=30000
export HISTCONTROL=ignoredups
shopt -s histappend
shopt -s histverify

# ----------------------------------------------------------------------------
# Sample:
# ----------------------------------------------------------------------------
history | tail -1
30042  | 2021-03-18 07:50:44 | ls -als

# ----------------------------------------------------------------------------
# Clear history and log out
# ----------------------------------------------------------------------------
alias hidetracks='cat /dev/null > ~/.bash_history && history -c && exit'

# ----------------------------------------------------------------------------
# Show command history from last Tuesday:
# ----------------------------------------------------------------------------
history | egrep "\| $(date -d'last Tuesday' +'%F')"

# ----------------------------------------------------------------------------
# Show command history from six days ago, 10-11 am:
# ----------------------------------------------------------------------------
history | egrep "\| $(date -d'-6 days' +'%F') (10|11):"

# ----------------------------------------------------------------------------
# Show command history for March 12, 7 am to March 16, 10 am:
# ----------------------------------------------------------------------------
range_hour() {
    TZ="$(date +"%Z")"; s=""; e=""; i=0
    se=$(date -d "${s}" +'%s'); ee=$(date -d "${e}" +'%s')
    sd="$(date -d "${s}")"; ed="$(date -d "${e}")"
    history | grep -E \
    "$(while [ ${se} -lt ${ee} ]; do
    st="$(date -d "${sd} + 1 hour" +'%F %H')"
    [[ ${i} < 1 ]] && echo -en "\| ${st}:*|" && (( i = i + 1 ))
    s="$(date -d "${sd} + 1 hour" +'%b %e %H')"
    sd="$(date -d "${s}")"; se=$(date -d "${s}" +'%s')
    echo -en "\| ${st}:*|"
    done | sed 's/|$//g')"
}
history | range_hour "Mar 12 07" "Mar 16 10"

# ----------------------------------------------------------------------------
# Show command history for March 18, 7:24 - 8:54 am:
# ----------------------------------------------------------------------------
range_minute() {
    TZ="$(date +"%Z")"; s=""; e=""; i=0
    se=$(date -d "${s}" +'%s'); ee=$(date -d "${e}" +'%s')
    sd="$(date -d "${s}")"; ed="$(date -d "${e}")"
    history | grep -E \
    "$(while [ ${se} -lt ${ee} ]; do
    st="$(date -d "${sd} + 1 minute" +'%F %H:%M')"
    [[ ${i} < 1 ]] && echo -en "\| ${st}:*|" && (( i = i + 1 ))
    s="$(date -d "${sd} + 1 minute" +'%b %e %H:%M')"
    sd="$(date -d "${s}")"; se=$(date -d "${s}" +'%s')
    echo -en "\| ${st}:*|"
    done | sed 's/|$//g')"
}
history | range_minute "Mar 18 07:24" "Mar 18 08:54"

# ----------------------------------------------------------------------------
# Add this function to your .bashrc to show the top 25 most frequently typed
# commands that are less than 20 characters and don't span multiple lines:
# ----------------------------------------------------------------------------
fc() {
    egrep -v "\\(\s)?$" | awk '{ s = ""; for (i = 6; i <= NF; i++) s = s $i " "; print s }' | sed 's/ /:/g' | awk 'length($0) < 20 { a[$0]++ } END { for ( i in a ) print a[i], i | "sort -rn | head -n25"}' | awk '$1 > max{ max=$1} { bar=""; i=s=10*$1/max;while(i-->0)bar=bar"*"; printf "%25s %15d %s %s", $2, $1,bar, "\n"; }' | sed 's/:/ /g'
}
history | fc

# ----------------------------------------------------------------------------
# Combine the previous `fc` function with the `range_hour` function to get a
# list of most frequently typed commands in the past 3 hours:
# ----------------------------------------------------------------------------
history | range_hour "$(date -d'-3 hours' +'%b %e %H')" "$(date +'%b %e %H')" | fc

The `fzf` command-line fuzzy search utility is tremendously useful for search your shell history for commands the syntax of which you can’t quite recall. You can find the simple installation instructions here and then add this handy alias to your `.bashrc`:

alias h='history | fzf'

Common Command Aliases

Some of the other handy command aliases that I use frequently:

# ----------------------------------------------------------------------------
# The `fc` function I mentioned earlier can help you determine which commands
# you type most often. Some of those minght be good candidates for an alias.
# ----------------------------------------------------------------------------
alias g="grep -i"
alias psg='ps -ef | grep '

# ----------------------------------------------------------------------------
# This produces output similar to `df -hP` but a little easier to follow
# ----------------------------------------------------------------------------
alias ddf='df -hP | column -t'

# ----------------------------------------------------------------------------
# This are probably the two most useful aliases for the `ls` command
# ----------------------------------------------------------------------------
alias l='ls -CF --color=always'
alias ll='ls -alhF --color=always'

# ----------------------------------------------------------------------------
# This alias for the `cd` command will follow symlinks to the target location.
# Many people just alias `cd` to use this syntax.
# ----------------------------------------------------------------------------
alias ccd='cd -P'

# ----------------------------------------------------------------------------
# Just a quick way to skip typing `cd` altogether for the most common
# scenarios
# ----------------------------------------------------------------------------
alias ..='cd ..'
alias ...='cd ../../'

# ----------------------------------------------------------------------------
# I don't normally use `nano`, but here is an alias sysadmins would find
# useful. It disabled long line wrapping, converts tabs to spaces, and sets
# the width of a tab to 2 columns instead of the default 8.
# ----------------------------------------------------------------------------
alias nano='nano -wET 2'

# ----------------------------------------------------------------------------
# If you're a fan of `tmux`, which I am, then a few simple aliases will can
# save you a lot of typing over time
# ----------------------------------------------------------------------------

alias tn='tmux new-session -s'                                # tmux new session
alias ta='tmux attach -t'                                     # tmux attach session
alias tl='tmux ls'                                            # list serrions
alias tk='tmux kill-session -s'                               # kill session 

# ----------------------------------------------------------------------------
# Generate a strong password
# ----------------------------------------------------------------------------
alias newpass="cat /dev/urandom | tr -dc 'a-zA-Z0-9^#@_:|<>{}=+$%' | fold -w ${1:-32} | head -n 1"

# ----------------------------------------------------------------------------
# Securely delete a file. There are better and faster tools, but this will
# work in a pinch.
# ----------------------------------------------------------------------------
filewipe() {
  p=""
  f=""
  re='^[0-9]+$'
  if [ ! -z "${p}" ] && [[ ${p} =~ ${re} ]] && [ ! -z "${f}" ] && [ -r "${f}" ]
  then
    for i in $(seq 1 ${p})
    do
      echo "Pass ${i} of ${p}"
      dd bs=1K count=$(stat --printf="%s / 1024 * 2 \n" "${f}" | bc) \
      iflag=fullblock if=/dev/urandom of="${f}" 2>/dev/null 1>&2
    done && /bin/rm -f "${f}"
  else
    echo "Can't access file ${f}"
  fi
}
# Example:
filewipe 3 /var/log/messages.1

# ----------------------------------------------------------------------------
# My favorite `ssh` alias for running commands on remote servers as root
# ----------------------------------------------------------------------------
3s() {
  h=""
  u=""
  c=""
  ssh -qtT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
  -o ConnectTimeout=3 -o BatchMode=yes -i /home/${u}/.ssh/id.rsa \
  ${u}@$i "sudo su - root -c '${c}'"
}
# Example:
3s ncc1701 root "df -hlP"

System Management Shortcuts

This is a short list of aliases and functions I have in my `.bashrc` for everyday sysadmin tasks.

# Show total allocated local disk space
dfalloc() {
  df -klP -t xfs -t ext2 -t ext3 -t ext4 -t reiserfs | \
  grep -oE ' [0-9]{1,}( +[0-9]{1,})+' | \
  awk '{sum_used += $1} END {printf "%.0f GB\n", sum_used/1024/1024}'
}

# Show total used local disk space
dfused() {
  df -klP -t xfs -t ext2 -t ext3 -t ext4 -t reiserfs | \
  grep -oE ' [0-9]{1,}( +[0-9]{1,})+' | \
  awk '{sum_used += $2} END {printf "%.0f GB\n", sum_used/1024/1024}'
}

# Show total available allocated local disk space
dffree() {
  df -klP -t xfs -t ext2 -t ext3 -t ext4 -t reiserfs | \
  grep -oE ' [0-9]{1,}( +[0-9]{1,})+' | \
  awk '{sum_used += $3} END {printf "%.0f GB\n", sum_used/1024/1024}'
}

# Find largest files
findhuge() {
  f=""
  if [ -z "${f}" ]
  then
    f="$(awk '{print $2}' <(grep "^/dev" /etc/mtab))"
  fi
  l=""; if [ -z "${l}" ]; then l=10; fi
  h=$(echo ${HOSTNAME} | awk -F. '{print $1}')
  d=$(date +'%Y-%m-%d %H:%M:%S')
  for i in ${f}; do
    find "${i}" -xdev -printf "${d},${h},%s,%TY-%Tm-%Td_%TH:%TM,%u:%g,%m,%n,%p\n" | \
    sort -t, -k3rn | head -${l}
  done | (echo "DATE,HOST,KB,MTIME,UID:GID,RWX,HL,PATH" && cat) | column -s',' -t
}
# Example:
findhuge /opt 10

# Monitor filesystem space and file size changes in real time
fswatch() {
  target_dir=""
  filename_mask=""
  max_file_age=""
  max_count=""
  watch -d -n 5 "df -kP; echo;
  find \"${target_dir}\" -maxdepth 2 -mindepth 1 -type f -name \"${filename_mask}*\" \
  -newermt \"-${max_file_age} seconds\" -exec ls -FlAt {} \; | \
  sort -k9V | column -t | head -${max_count}"
}
# Example:
fswatch /var/log "*" 10 20

# Find the number of physical CPUs (even if hyper-threading is enabled)
alias corecount="lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l"

Correcting Typos

There are certain commands I mistype on a regular basis. While `.bashrc` is not the best way of addressing this issue ( for this I would recommend using AutoHotkey on Windows or AutoKey on Linux), but to a limited extent it’s not a terrible idea:

alias grpe='grep'
alias hsitory='history'
alias sl='ls'
alias cd..='cd ..'

Copying, Syncing, and Archiving Data

The joke about typing a useful `tar ` command without googling has some truth to it. The same goes for `rsync`, `dd`, and even the good old `cp`. Here are some relevant aliases from my `.bashrc`:

# ----------------------------------------------------------------------------
# A function to create a compressed tarball of a directory in the current
# folder, if there's sufficient space
# ----------------------------------------------------------------------------
targz() {
  d=""
  if [ -d "${d}" ]
  then
    if [ $(stat -f --printf="%a * %s / 1024\n" . | bc) -gt $(du -sk ./"${d}" | awk '{print $1}') ]
    then
      tar cvfz "${d}.tgz" "${d}"
    else
      echo "Low space in $(pwd)"
    fi
  else
    echo "Can't access ${d}"
  fi
}

# Running this will then produce folder.tgz in your home directory
cd ~ && targz folder

# ----------------------------------------------------------------------------
# The following function would rsync stuff from the specified source to the
# target with all the common and useful options.
# ----------------------------------------------------------------------------
myrsync() {
  s=""
  t=""
  if [ -d "${s}" ]
  then
    if [ ! -d "${t}" ]
    then
      echo "Creating target ${t}"
      mkdir -p "${t}"
    fi
    echo "Checking the size of ${s}"
    if [ $(du -sk "${s}" | awk '{print $1}') -lt \
    $(df -k "${t}" | sed 's/ \+/ /g' | grep -oP "(?<= )[0-9]{1,}(?= [0-9]{2}%)") ]
    then
      rsync -avuKxh --progress --log-file="$(mktemp)" "${s}" "${t}"
    else
      echo "Low space in ${t}"
    fi
  else
    echo "Can't access ${s}"
  fi
}

# An example of how to run the `myrsync` function:
myrsync /etc /opt/backups/$(date +'%Y-%m-%d_%H%M%S')

# ----------------------------------------------------------------------------
# Here's a function to find files in the source directory that
# match the specified filename mask and rsync them to another folder:
# ----------------------------------------------------------------------------
find-rsync() {
  s=""
  t=""
  m=""
  if [ -d "${s}" ] && [ ! -z "${m// }" ]
  then
    if [ ! -d "${t}" ]
    then
      echo "Creating target ${t}"
      mkdir -p "${t}"
    fi
    find "${s}" -type f -name "${m}" -print0 | \
    rsync -avKx --relative --files-from=- --from0 / "${t}"
  else
    echo "Can't access ${s} or filename mask is not set"
  fi
}

# An example of how to run the `find-rsync` function to copy all `*.conf` files from /etc to a backup folder:
find-rsync /etc /opt/backups/$(date +'%Y-%m-%d_%H%M%S') "*\.conf"

# ----------------------------------------------------------------------------
# Find all RAR archives in the current folder and extract only certain
# types of files from them:
# ----------------------------------------------------------------------------
unrar-here2() {
  t=""
  if [ ! -z "${t}" ]
  then
    find . -maxdepth 1 -mindepth 1 -type f -name "*\.rar" -exec \
    unrar e -kb -o+ {} \
    $(for i in $(echo ${t} | sed 's/,/ /g')
    do echo -ne "*.$i "
    done) \;
  fi
}

# Here's how this would work to extract common video filetypes
unrar-here2 "mkv,mp4,avi"

# ----------------------------------------------------------------------------
# Extract an archive file by running the correct command base on the
# filename extension
# ----------------------------------------------------------------------------
extract () {
  if [ -f "" ] ; then
    case $1 in
      *.tar.bz2)  tar xjf    ""    ;;
      *.tar.gz)   tar xzf    ""    ;;
      *.bz2)      bunzip2    ""    ;;
      *.rar)      rar x      ""    ;;
      *.gz)       gunzip     ""    ;;
      *.tar)      tar xf     ""    ;;
      *.tbz2)     tar xjf    ""    ;;
      *.tgz)      tar xzf    ""    ;;
      *.zip)      unzip      ""    ;;
      *.Z)        uncompress ""    ;;
      *)      echo "Unknown file type" ;;
    esac
  else
    echo "Can't access "
  fi
}

Handy Network Aliases

I may not need to use these often, but when I do, I am usually in a hurry and have no time for googling.

# Show local primary IP address
alias localip='ifconfig | sed -rn "s/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p"'

# Show public (Internet) IP address
alias publicip='wget http://ipecho.net/plain -O - -q ; echo'

# Scan subnet for active systems
subnetscan() {
  nmap -sn  -oG - | awk '$4=="Status:" && $5=="Up" {print $2}'
}
# Example:
subnetscan 192.168.122.1/24

# Scan subnet for available IPs
subnetfree() {
  nmap -v -sn -n  -oG - | awk '/Status: Down/{print $2}'
}
# Example:
subnetfree 192.168.122.1/24

# Quick network port scan of an IP
portscan() {
  nmap -oG -T4 -F  | grep "\bopen\b"
}
# Example:
portscan 192.168.122.37

# Stealth syn scan, OS and version detection, verbose output
portscan-stealth() {
  nmap -v -sV -O -sS -T5 
}
# Examples:
portscan-stealth 192.168.122.137
portscan-stealth 192.168.122.1/24

# Test port connection
alias portcheck='nc -v -i1 -w1'
# Example:
portcheck 192.168.122.137 22

# Detect frame drops using `ping`
pingdrops() {
  ping  | \
  grep -oP --line-buffered "(?<=icmp_seq=)[0-9]{1,}(?= )" | \ awk '$1!=p+1{print p+1"-"$1-1}{p=$1}' } # Example: pingdrops 192.168.122.137 # Quickly test network throughput between two servers via SSH bandwidth-test() { yes | pv | ssh  "cat > /dev/null"
}
# Example:
bandwidth-test 192.168.122.137

# Identify local listening ports and services
localports() {
  for i in $(lsof -i -P -n | grep -oP '(?<=\*:)[0-9]{2,}(?= \(LISTEN)' | sort -nu)
  do
    lsof -i :${i} | grep -v COMMAND | awk -v i=$i '{print $1,$3,i}' | sort -u
  done | column -t
}