Connect with us

Crypto Mining

Using a Script to Send Desktop Notifications from Your Linux Terminal

Published

on

Tomasz Waraksa

Introduction: Sending Desktop Notifications

Sometimes it's useful to get visual feedback from a script. For example, when script or cron job completes or when a long-running build fails, or when there is an urgent problem during script execution. Desktop applications can do this with popup notifications. But it can be done from a script too!

:::tip You can use script commands to send yourself desktop notifications and reminders.

:::

The below code has been written and tested on Linux. What about MacOS? Well… it can be done too, with a bit of effort.

Sending notifications from Linux terminal

To send notifications from the Linux terminal, use the notify-send command. Run which at to see if it's present. If not, install it with your package manager of choice, for example

sudo apt install notify-send

A few examples of simple notifications:

notify-send "Dinner ready!"
notify-send "Tip of the Day" "How about a nap?"

You can customize the notification with options such as urgency level, custom icon, etc. Find out more with man notify-send. You can use a small set of HTML tags in the notification body, to give your notifications nice touch. On top of that, URLs are rendered as clickable, for example:

notify-send -u critical 
  "Build failed!" 
  "There were <b>123</b> errors. Click to see the results: http://buildserver/latest"

Sent notifications are picked up by the desktop environment and displayed just like any other notification. They will have the same consistent look, feel, and behaviour.

Combine notify-send with AT

We all know cron, used to schedule commands at regular intervals. Command AT is used to schedule single execution of a command at a specified time. If you run it like this:

at 12:00

it will start in interactive mode, where you can enter commands to execute at given time. This isn't useful for scripts. Luckily, at accepts parameters from standard input, so we can use it this way:

echo "npm run build" | at now + 1 minute
echo "backup-db" | at 13:00

There are many ways of specifying time. From absolute time such as 10:00 through relative time such as now + 2 hours to special times such as noon or midnight. We can combine it with notify-send to show ourselves reminders at some time in future, for example:

echo "notify-send 'Stop it and go home now' 'Enough for today.' -u critical" | at now

REMIND command

Now, let's build a custom bash command for sending ourselves reminders. How about something as simple and human-friendly as:

remind "I'm still here" now
remind "Time to wake up!" in 5 minutes
remind "Dinner" in 1 hour
remind "Take a break" at noon
remind "It's Friday pints time!" at 17:00

This is better than Alexa! How to get this goodness?

See the code below. It defined bash function called remind which supports the above syntax. The actual work is done in the last two lines. The rest is responsible for help, parameter validation etc. which rougly matches the proportion of useful code vs necessary white-noise in any large application :wink: Save the code somewhere, for example in ~/bin/remind file and load the function in your .bashrc profile:

source ~/bin/remind

Reload the terminal, then type remind to see the syntax. Enjoy!

#!/usr/bin/env bash

function remind () {
  local COUNT="$#"
  local COMMAND="$1"
  local MESSAGE="$1"
  local OP="$2"
  shift 2
  local WHEN="[email protected]"

  # Display help if no parameters or help command
  if [[ $COUNT -eq 0 || "$COMMAND" == "help" || "$COMMAND" == "--help" || "$COMMAND" == "-h" ]]; then
    echo "COMMAND"
    echo "    remind <message> <time>"
    echo "    remind <command>"
    echo
    echo "DESCRIPTION"
    echo "    Displays notification at specified time"
    echo
    echo "EXAMPLES"
    echo '    remind "Hi there" now'
    echo '    remind "Time to wake up" in 5 minutes'
    echo '    remind "Dinner" in 1 hour'
    echo '    remind "Take a break" at noon'
    echo '    remind "Are you ready?" at 13:00'
    echo '    remind list'
    echo '    remind clear'
    echo '    remind help'
    echo
    return
  fi

  # Check presence of AT command
  if ! which at >/dev/null; then
    echo "remind: AT utility is required but not installed on your system. Install it with your package manager of choice, for example 'sudo apt install at'."
    return
  fi

  # Run commands: list, clear
  if [[ $COUNT -eq 1 ]]; then
    if [[ "$COMMAND" == "list" ]]; then
      at -l
    elif [[ "$COMMAND" == "clear" ]]; then
      at -r $(atq | cut -f1)
    else
      echo "remind: unknown command $COMMAND. Type 'remind' without any parameters to see syntax."
    fi
    return
  fi

  # Determine time of notification
  if [[ "$OP" == "in" ]]; then
    local TIME="now + $WHEN"
  elif [[ "$OP" == "at" ]]; then
    local TIME="$WHEN"
  elif [[ "$OP" == "now" ]]; then
    local TIME="now"
  else
    echo "remind: invalid time operator $OP"
    return
  fi

  # Schedule the notification
  echo "notify-send '$MESSAGE' 'Reminder' -u critical" | at $TIME 2>/dev/null
  echo "Notification scheduled at $TIME"
}

Script Notifications on MacOS

Although there is no notify-send on MacOS, notifications can be sent with ActionScript. For example:

osascript -e 'display notification "Wake up!" with title "Reminder"'

Also, there's at available, so things should be easy? Well, not so. Sadly, MacOS is makes it increasingly difficult for power users to use their powers …

First, command at is disabled by default. Even if you run it, nothing will happen at scheduled time, because atrun daemon is disabled, and no user account is allowed to use it by default.

To allow yourself to use the command, edit /var/at/at.allow file and add your user name.

sudo open -a textedit /var/at/at.allow

Then enable atrun daemon:

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist

Let's try sending a notification:

osascript -e 'display notification "Wake up!" with title "Reminder"' | at now

… and nothing happens. Why?

The daemon is not allowed to interact with the desktop, nor anything else for that matter. To fix this, go to System Preferences / Security & Privacy / Privacy / Full Disk Access and add atrun to the list. The file is found at /usr/libexec/atrun path. You want to see this:

… only how to select this file? MacOS won't display system folders in the file selector, even if you've been asked to authenticate as admin just a minute ago. I managed to circumvent it by adding my `/usr` folder to list of favourite folders in Finder:

Last but not least, for some even this won't work. AT will not send these pesky notifications, period. It has something to do with script executing not in userspace. You can find more information and solution here: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard. This is what helps:

# Install reattach-to-user-namespace utility
brew install reattach-to-user-namespace
# Run notification command as follows
reattach-to-user-namespace osascript -e 'display notification "Wake up!" with title "Reminder"' | at now

Phew. Hopefully, it works for you too, and you can use remind script on your Mac as well! Happy weekend!

Software License

Permission is hereby granted, free of charge, to any person obtaining a copy of software published on this website and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions, unless stated explicitly otherwise:

  • The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  • The software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement.
  • In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

Continue Reading

Latest

Companies

Public Companies Hold A Combined $11.8 Billion Worth Of BTC On Their Balance Sheet – See The Leading Firms

Crypto Mining3 weeks ago

Aliyu Pokima Publicly traded companies went all-in on Bitcoin in 2021 led by Michael Saylor’s MicroStrategy.Other firms on the list...

Indian Regulator SEBI Wants Mutual Funds to Stay Away From Crypto Investments Until Legislation Is Finalized

Crypto Mining3 weeks ago

Kevin Helms The Securities and Exchange Board of India (SEBI) has reportedly asked mutual fund companies not to get involved...

XRP Creator Chris Larsen Proposes Strategy To Incentivize Bitcoin Miners To Move Away From Proof-of-Work

Crypto Mining1 month ago

Brenda Ngari XRP inventor and Ripple executive chairman Chris Larsen has unveiled a plan to entice miners of the flagship...

Iceland Refuses to Power New Bitcoin Farms Amid Electricity Shortages

Crypto Mining1 month ago

Lubomir Tassev Cryptocurrency mining is among several energy-intensive industries hurt by a power deficit in Iceland. The country’s main utility...

Public Bitcoin Miners Are Increasing Their BTC Treasuries

Crypto Mining2 months ago

Dylan LeClair And Sam Rule Publicly-traded bitcoin mining firms have been accumulating and holding bitcoin at an increasing rate.The below...

NASDAQ-Listed HIVE Blockchain to Expand Data Center in New Brunswick, Canada With 40 Megawatts Capacity

Crypto Mining3 months ago

Bitcoin.com PR HIVE Blockchain is set to expand its data center campus in New Brunswick, Canada with 40 megawatts capacity....

%d bloggers like this: