“纸糊”的语音提醒助手

记得喝水,记得动一动

用cron定时播放语音,哈哈~btw,我实验的环境是Linuxmint 19.

生成语音

用百度账号登录,在语音广播开放平台生成简短语音,并重命名保存。例如:

xx@xx:~$ ll /opt/remindme/
total 280K
-rw-r--r-- 1 root root  11K 17:29 xiabandaka.mp3
-rw-r--r-- 1 root root 5.5K 17:29 shuijiao.mp3
-rw-r--r-- 1 root root 122K 17:29 penguin.png
-rwxr-xr-x 1 root root  738 17:29 notify-send-call
-rw-r--r-- 1 root root 7.2K 17:29 jiayou.mp3
-rw-r--r-- 1 root root 8.3K 17:29 heshui.mp3
-rw-r--r-- 1 root root  11K 17:29 dongyidong.mp3
-rwxr-xr-x 1 root root  261 17:33 showtip


安装播放器

apt install mplayer

创建cron

#remindme wushui
45 12 * * * /opt/remindme/showtip "该午睡啦!" shuijiao >> /home/oliver/bdsay/rmd.log 2>&1

#remindme jiayou
15 9 * * * /opt/remindme/showtip "你是最棒的,加油!" jiayou >> /home/oliver/bdsay/rmd.log 2>&1

#remindme heshui
38 * * * * /opt/remindme/showtip "该喝水啦!" heshui >> /home/oliver/bdsay/rmd.log 2>&1

#remindme dongyidong
45 * * * * /opt/remindme/showtip "伸伸胳膊伸伸腿,扭扭脖子扭扭腰!" dongyidong >> /home/oliver/bdsay/rmd.log 2>&1

#remindm xiabandaka
*/15 17-19 * * * /opt/remindme/showtip "快下班啦,记得打卡!" xiabandaka >> /home/oliver/bdsay/rmd.log 2>&1

#remindme xiabandaka jiaban
*/10 19-21 * * * /opt/remindme/showtip "记得打卡!" xiabandaka >> /home/oliver/bdsay/rmd.log 2>&1

#remindme shuijiao
*/5 21-23 * * * /opt/remindme/showtip "你该睡觉啦!" shuijiao >> /home/oliver/bdsay/rmd.log 2>&1

嘿嘿嘿,老带劲了……

脚本实例

资源都放在 /opt/remindme 下, showtip :

#!/bin/bash
home_remindme=/opt/remindme
echo $home_remindme
$home_remindme/notify-send-call $1 -i $home_remindme/penguin.png -u critical
/usr/bin/paplay /usr/share/sounds/LinuxMint/stereo/phone-incoming-call.ogg
/usr/bin/mplayer -ao alsa $home_remindme/$2.mp3

卡壳讲解

在桌面环境下,打开一个terminal,然后使用notify-send是正常的,但是cron下直接使用notify-send就不行了。你可以简单的理解为,这是因为crontab没有桌面环境。

找答案,至少还得是bing……实在不行就搜英文关键词……再不行就上论坛,果然,论坛找到了答案。

notify-send communicates over the dbus session bus but cron jobs are
not part of any graphical user session; are not provided the session
bus address of whichever graphical session runs the desktop notifier
to be contacted. For Mint 19 and supposedly Ubuntu 18.04 this is
easily remedied by manually providing the cron job with the
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
environment variable but that socket does not in fact exist on Mint 18
and supposedly Ubuntu 16.04.

最优解

通过脚本初始化DBUS_SESSION_BUS_ADDRESS,然后调用notify-send.

论坛有人提供了一个脚本,也就是上文引用的 notify-send-call ,Linuxmint 18/19 都适用。

#!/bin/sh
if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then 
    if [ -z "$LOGNAME" ]; then
        EUID=$(id -u)
    else
        EUID=$(id -u "$LOGNAME")
    fi
    [ -z $EUID ] && exit

    if [ -S /run/user/$EUID/bus ]; then
        export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$EUID/bus"
    else
        SESSION=$(loginctl -p Display show-user "$LOGNAME" | cut -d= -f2)
        [ -z "$SESSION" ] && exit
        LEADER=$(loginctl -p Leader show-session "$SESSION" | cut -d= -f2)
        [ -z $LEADER ] && exit
        OLDEST=$(pgrep -o -P $LEADER)
        [ -z $OLDEST ] && exit
        export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$OLDEST/environ)
        [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && exit
    fi
fi
notify-send "$@"

参考文章

Linux下防沉迷、防熬夜猝死的代码
[Mint 18, 19] Using notify-send from a user crontab