In my work, I often jump between a variety of machines. I have increasingly begun to rely on simple interfaces that work cross-platform in my environment. It makes these scriptable and usable no matter where you are.

notify()

One such example is this notify function. It allows you to call one function to display system notifications. Your mileage may vary, but it’s worked well for me.

Just add the following to your shell startup files and reload..

# cross platform notification system
# Usage: notify "Title" "Message"
notify() {

local title="${1:-"Notification"}"
local message="${2:-}"

# macOS
if command -v osascript >/dev/null 2>&1; then
  osascript -e "display notification \"$message\" with title \"$title\""

# WSL: Detect *first* before generic Linux!
elif grep -qi microsoft /proc/version 2>/dev/null && command -v powershell.exe >/dev/null 2>&1; then

    powershell.exe -NoProfile -Command "Import-Module BurntToast; New-BurntToastNotification -Text \"${title}\", \"${message}\""

# Linux/Unix with notify-send
elif command -v notify-send >/dev/null 2>&1; then
  notify-send "$title" "$message"

# Windows native Git Bash, msg.exe
elif command -v msg.exe >/dev/null 2>&1; then
  msg.exe * "$title: $message"

# Fallback to wall
elif command -v wall >/dev/null 2>&1; then
  echo "$title: $message" | wall
else
  echo "$title: $message"
fi

}

Usage

notify "Title" "This is a test of the Emergency Broadcast System"

On my systems, this pops up a system notification. The one catch is that on modern Macs you must enable terminal notifications by opening Script Editor one time and running the following:

display notification "Test notification" with title "Script Editor"

This will prompt you (with a notification) to allow terminal notifications.

More interfaces

I’m still developing these but the following are pretty handy as well.

say command

Since I split my shell startup into multiple files, I define the say command so it is present on linux and works like on the mac. Of course espeak voices are not as nice as on mac but they do have their place as another kind of notification or even a toy.

# macOS-style `say` command on Linux using espeak
if [[ "$(uname -s)" == "Linux" ]] && command -v espeak >/dev/null; then
  alias say='espeak -s 160 -p 60 -v en-us+f2'
fi

You’ll need to install espeak with your preferred package manager. For apt it’s just

apt install espeak 

man2pdf

This is one I have used on mac for years.

# Convert man page to PDF (macOS only)
man2pdf() {
  man -t "$1" | open -f -a /Applications/Preview.app
}

Usage:

man2pdf grep 

This will launch a man page in Preview as an attractive pdf. I missed that command on linux but it’s as easy as doing the following:

# Render man page as ps then as pdf using the ps2pdf application
# functional equivalent to man2pdf on mac.

man2pdf() {
  local page="${1:?Usage: man2pdf <manpage>}"
  local tmpfile
  tmpfile="$(mktemp --suffix=.pdf /tmp/man2pdf-XXXXXX.pdf)"

  # Convert manpage to PDF
  man -t "$page" | ps2pdf - "$tmpfile"
  # Open the PDF using xdg-open (works on most desktops)
  xdg-open "$tmpfile" >/dev/null 2>&1 &
}

Same usage. easy peasy.

clip and paste

Another really useful cross platform command is clip and paste. Having predictable interfaces like this is definitely adminjitsu.

On Mac

# macOS clipboard
# for consistency with linux environment
alias clip='pbcopy'
alias paste='pbpaste'

On Linux

# Linux clipboard (assumes xclip is installed)
alias clip='xclip -selection clipboard'
alias paste='xclip -selection clipboard -o'

You’ll need to install xclip with your preferred package manager. For apt it’s just

sudo apt install xclip 

That is a really powerful command that allows you to do things like:

find . -type f ! -path "*/.git/*" ! -path "*/venv/*" | clip 
paste

and now the output is on your system clipboard and ready to paste anywhere.

Conclusion

These are just a few small examples of a concept I am really starting to embrace. I look forward to adding more as time goes on!