THE PROBLEM
Crontab does work - but just aside, not in interaction with users. How to make crontab talk to currently logged-in user by automatically perceivable prompt output? For example, a wake-up call, an alarm clock, ringing every minute for user1, without user1 having to do anything for receiving the message, except being present at the computer, with open eyes and ears?
Side note The timing, every minute… - of course, this is just a technical example, in reality a more meaningul and useful timing is chosen.
IMAGINE THIS
Computer = switched off
user1 = dave
dave:
*switching on computer*
*logs into his user account "dave"*
*lands in GUI desktop*
*starts mate-terminal*
Checking who is logged in and what they are doing:
dave@LocalMachine:~$ w
12:46:42 up 4:22, 2 users, load average: 0.18, 0.44, 0.43
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
dave tty7 :0 08:24 4:22m 6:57 0.31s mate-session
Creating executable bash script "alarm_clock" in /tmp/
dave@LocalMachine:~$ emacs -nw /tmp/alarm_clock && chmod +x /tmp/alarm_clock
# Alarm clock displaying current time and ringing.
#
# Copyleft 🄯 2024
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
#!/bin/bash
# Passes 2 things to standard output of whoever is executing this script:
## string "current date" - by part $(date)
## acoustic alarm signal - by sequence \a within "" of echo behaving differently by set -e option
echo -e "$(date) \a"
Creating crontab with 1 cronjob for him alone,
with an alarm clock ringing every minute,
expecting a prompt of current time while job execution on screen and an alarm sound,
as if he had given standard input into mate-terminal bash echo -e "$(date) \a"
dave@LocalMachine:~$ crontab -e
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
# Variables
## Otherwise will spill out "TERM environment variable not set." as 2
### It is set - but just for user "dave", not crontab itself
#### … until now:
TERM=xterm
# Test
## sh-file "alarm_clock"
### executable for dave, dave (group) & others
### containing shebang bash
### containing NEWLINE as last character of the document
### working when being executed by dave
### redirecting standard output, split up into results.log for successful parts, and errors.log for errors
* * * * * /tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log
THE OUTPUT
dave@LocalMachine:~$ tail -f /var/log/syslog
Jan 2 13:52:01 LocalMachine CRON[9786]: (dave) CMD (/tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log)
Jan 2 13:53:01 LocalMachine CRON[9807]: (dave) CMD (/tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log)
Jan 2 13:53:28 LocalMachine kernel: [19747.884955] [UFW BLOCK] IN=enp0s25 OUT= MAC=01:00:5e:00:00:01:38:43:7d:3a:bd:51:08:00 SRC=192.168.0.1 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=26121 PROTO=2
Jan 2 13:54:01 LocalMachine CRON[9813]: (dave) CMD (/tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log)
Jan 2 13:55:01 LocalMachine CRON[9818]: (dave) CMD (/tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log)
Jan 2 13:55:33 LocalMachine kernel: [19872.884504] [UFW BLOCK] IN=enp0s25 OUT= MAC=01:00:5e:00:00:01:38:43:7d:3a:bd:51:08:00 SRC=192.168.0.1 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=26123 PROTO=2
Jan 2 13:55:46 LocalMachine com.canonical.indicator.sound-gtk2[1651]: ** (process:2001): WARNING **: music-player-bridge.vala:262: Could not create a desktopappinfo instance from app: firefox.desktop
Jan 2 13:55:46 LocalMachine com.canonical.indicator.sound-gtk2[1651]: ** (process:2001): WARNING **: music-player-bridge.vala:181: Could not create app_info for path firefox
Jan 2 13:55:46 LocalMachine com.canonical.indicator.sound-gtk2[1651]: Getting out of here
Jan 2 13:56:01 LocalMachine CRON[9857]: (dave) CMD (/tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log)
dave@LocalMachine:~$ emacs -nw /tmp/my_command_results.log
-e Tue 2 Jan 14:01:01 CET 2024 ^G
side note
That ^G
, that's unexpected.
Can't explain to me where that comes from, judging the script just contained
a simple echo -e "$(date) \a"
and passing this manually into mate-terminal bash gives standard output Tue 2 Jan 14:06:57 CET 2024
+ a popping sound as alarm signal.
Now it becomes even weirder
Having realized I've took a look into that file with en editor, instead simply invocing cat
, I've repeated with process with the latter, triggering strange output
dave@LocalMachine:~$ cat /tmp/my_command_results.log
-e Tue 2 Jan 14:11:01 CET 2024
PLUS a popping sound as alarm signal, as if I hadn't invoced cat
but an echo
like for example echo -e "$(date) \a"
! How weird is that?!
my_command_errors.log is empty either way:
dave@LocalMachine:~$ cat /tmp/my_command_errors.log
dave@LocalMachine:~$ emacs -nw /tmp/my_command_errors.log
dave@LocalMachine:~$
TEST PHASE 2: IMPLEMENTATION
Now with that all out of the way, dave is switching the crontab active, by creating a copy of the line, removing the part redirecting the output into files, away from standard output, and commenting the copy source out
Before
dave@LocalMachine:~$ crontab -e
* * * * * /tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log
After
dave@LocalMachine:~$ crontab -e
# * * * * * /tmp/alarm_clock > /tmp/my_command_results.log 2>/tmp/my_command_errors.log
* * * * * /tmp/alarm_clock
THE OUTPUT AFTER ACTIVATION
dave@LocalMachine:~$ tail -f /var/log/syslog
Jan 2 14:28:02 LocalMachine CRON[10175]: (dave) CMD (/tmp/alarm_clock)
Jan 2 14:28:02 LocalMachine CRON[10174]: (CRON) info (No MTA installed, discarding output)
Jan 2 14:28:53 LocalMachine kernel: [21872.877424] [UFW BLOCK] IN=enp0s25 OUT= MAC=01:00:5e:00:00:01:38:43:7d:3a:bd:51:08:00 SRC=192.168.0.1 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=26155 PROTO=2
Jan 2 14:29:01 LocalMachine CRON[10182]: (dave) CMD (/tmp/alarm_clock)
Jan 2 14:29:01 LocalMachine CRON[10181]: (CRON) info (No MTA installed, discarding output)
Jan 2 14:30:01 LocalMachine CRON[10191]: (dave) CMD (/tmp/alarm_clock)
Jan 2 14:30:01 LocalMachine CRON[10190]: (CRON) info (No MTA installed, discarding output)
Jan 2 14:30:58 LocalMachine kernel: [21997.876838] [UFW BLOCK] IN=enp0s25 OUT= MAC=01:00:5e:00:00:01:38:43:7d:3a:bd:51:08:00 SRC=192.168.0.1 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=26157 PROTO=2
Jan 2 14:31:01 LocalMachine CRON[10195]: (dave) CMD (/tmp/alarm_clock)
Jan 2 14:31:01 LocalMachine CRON[10194]: (CRON) info (No MTA installed, discarding output)
Jan 2 14:32:01 LocalMachine CRON[10202]: (dave) CMD (/tmp/alarm_clock)
Jan 2 14:32:01 LocalMachine CRON[10201]: (CRON) info (No MTA installed, discarding output)
Aside of missing redirection output no changes, still everything is quiet in the room with the computer, although according to syslog the cronjob is executed every minute. And a prompt of the current date as if the user manually types in echo "$(date)"
and then RET, doesn't appear either. Silence on all channels.
How can that be? And more important: What to change for automatically receiving a popping sound as alarm signal every minute and display of current time of that event on the screen?
man ascii
: 007 7 07 BEL '\a' (bell). The terminal rendersBEL
as^G
(BEL is octal 007, G is octal 107).cron
explicitly runs jobs in the background. stdin is from /dev/null, stdout and stderr are saved and (by default) emailed to the user. The job does not inherit a terminal (there may be no logged-in user at all, and how would you set window focus anyway). Sound is less restrictive (I can* * * * * spd-say -r -60 -p -50 -i -40 Doh
).cron
is not meant to interact with users, and your usecase doesn't sound like a job forcron
,#!/bin/bash
in the first line. I doubt the kernel will execute it (but it can still be executed as a parameter tobash
, but not in your case).