Lolcatme

Reading time: about 2 minutes

For months I mused about a way to funnel everything in a terminal through lolcat. Somewhere along the way I came across Bash’s DEBUG signal. From The Linux Documentation Project on trap: “If one of the signals is DEBUG, the list of COMMANDS is executed after every simple command.” This is the lead I needed!

In prep, install lolcat to the system ruby:

$ gem install lolcat

Drop this into your .bash_profile, and watch the rainbows happen.

function lolcatme() {
  which -s lolcat
  if [ $? -ne 0 ]; then
    echo no lolcat
    return 0
  fi

  if [[ "$BASH_COMMAND" == "$PROMPT_COMMAND" ]]; then
    return 0
  fi

  if [ -e /etc/bashrc_Apple_Terminal ]; then
    grep -F --quiet "'$BASH_COMMAND'" /etc/bashrc_Apple_Terminal
    if [ $? -eq 0 ]; then
      echo terminal boot sequence
      return 0
    fi
  fi

  unsafe_commands=('vi' 'vim' 'nano' 'emacs' 'open' 'bash' 'fish' 'zsh' 'man')
  unsafe_commands+=('shell_session_history_check' 'update_terminal_cwd')
  for cmd in "${unsafe_commands[@]}"; do
    if [[ "'"$BASH_COMMAND"'" =~ $cmd.* ]]; then
      echo unsafe command: $BASH_COMMAND
      return 0
    fi
  done

  $BASH_COMMAND | lolcat
  return 2
}

shopt -s extdebug

trap 'lolcatme' DEBUG

Similarly, for Fish Shell, place this in your ~/.config/fish/config.fish:

function fish_user_key_bindings
  bind \r 'lolcatme'
end

function lolcatme
  set -l cmd (commandline)
  set -l first (commandline --tokenize)[1]

  if not contains $first vi vim emacs nano open bash fish zsh
    commandline --append ' | lolcat'
  end

  commandline -f execute
end

And for ZSH, something like this:

setopt DEBUG_BEFORE_CMD

function lolcatme() {
  eval ${ZSH_DEBUG_CMD} | lolcat
  setopt ERR_EXIT
}

trap 'lolcatme' DEBUG

I ran into a particular problem with oh my zsh using this. In order to render the prompt, OMZ calls several hundred functions, each in turn calling lolcatme(). Unfortunately, this performance hit is substantial and makes the shell almost unusable.

The result is rather glorious:

Lolcatme in action


Date: 2017-Apr-08
Tags: bash fish prank lolcat
Previous: Ruby 2.2.2 Splat Bug
Next: Deploying Amber with Docker

This page was originally published as a github gist and was imported in December 2017.
Original Gist here.