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!