Top 5 Bash Functions

Here are a few bash functions that I find myself using all the time.

Functions are great where you have something that's slightly more complex than an alias, or wants to parse out its arguments, but isn't big enough to turn into a proper script. Drop these into your ~/.bashrc file (and source ~/.bashrc) and you're good to go!

Hope one or two of these are helpful/interesting.

1. ssht

Only came across this one fairly recently, but it's nice - you can combine the joys of ssh and tmux to drop you automagically into a given named session - I use sshgc (with my initials), so as not to clobber anyone else's session. (Because ssh and then tmux attach is so much typing!)

ssht() {
  local SESSION_NAME=sshgc
  command ssh -t "$1" tmux new-session -A -s $SESSION_NAME
}

2. lead

lead is a combination of ls -l and head, showing you the most recent N files in the given (or current) directory:

lead() {
  if [[ "$2" =~ ^[0-9]+$ ]]; then
    command ls -lt "$1" | head -n $2
  else
    # This version works with multiple args or globs
    command ls -lt "$@" | head -n 30
  fi
}

Or if you're using exa instead of ls, you can use:

lead() {
  if [[ "$2" =~ ^[0-9]+$ ]]; then
    command exa -l -s newest -r --git --color always "$1" | head -n $2
  else
    command exa -l -s newest -r --git --color always "$@" | head -n 30
  fi
}

Usage:

# Show the 30 most recent items in the current directory
lead
# Show the 30 most recent items in the given directory
lead /etc
# Show the 50 most recent items in the current directory
lead . 50
# Show the most recent items beginning with `abc`
lead abc*

3. l1

This ("lowercase L - one", in case it's hard to read) is similar in spirit to lead, but it just returns the filename of the most recently modified item in the current directory.

l1() {
  command ls -t | head -n1
}

This can be used in places where you'd use bash's !$ e.g. to edit or view some file you just created:

solve_the_meaning_of_life >| meaning.txt
cat !$
42!
# OR: cat `l1`

But l1 can also be used in situations where the filename isn't present in the previous command. For instance, I have a script that produces a pdf invoice from a given text file, where the pdf name is auto-derived from the text file name. With l1, I can just do:

invoice ~/Invoices/cust/Hours.2107
evince `l1`

4. xtitle

This is a cute hack that lets you set the title of your terminal to the first argument that doesn't being with a '-':

function xtitle() {
  if [ -n "$DISPLAY" ]; then
    # Try and prune arguments that look like options
    while [ "${1:0:1}" == '-' ]; do
      shift
    done
    local TITLE=${1:-${HOSTNAME%%.*}}
    echo -ne "\033]0;"$TITLE"\007"
  fi
}

Usage:

# Set your terminal title to 'foo'
xtitle foo
# Set your terminal title to the first label of your hostname
xtitle

I find this nice to use with ssh (or incorporated into ssht above) e.g.

function sshx() {
  xtitle "$@"
  command ssh -t "$@"
  local RC=$?
  xtitle
  return $RC
}

This (hopefully) sets your terminal title to the hostname you're ssh-ing to, and then resets it when you exit.

5. line

This function lets you select a particular line or set of lines from a text file:

function line() {
  # Usage: line <line> [<window>] [<file>]
  local LINE=$1
  shift
  local WINDOW=1
  local LEN=$LINE
  if [[ "$1" =~ ^[0-9]+$ ]]; then
    WINDOW=$1
    LEN=$(( $LINE + $WINDOW/2 ))
    shift
  fi
  head -n "$LEN" "$@" | tail -n "$WINDOW"
}

Usage:

# Selecting from a file with numbered lines:
$ line 5 lines.txt
This is line 5
$ line 5 3 lines.txt
This is line 4
This is line 5
This is line 6
$ line 10 6 lines.txt
This is line 8
This is line 9
This is line 10
This is line 11
This is line 12
This is line 13

And a bonus alias:

alias bashrc="$EDITOR ~/.bashrc && source ~/.bashrc"