自己总是在电脑前一坐半天乃至一天,不利于健康不说,长时间纠结某个问题往往事倍功半,所以就写了这么个脚本,初衷就是定时提醒自己起身放松一下。
这个脚本作用很简单,添加到crontab,0 8-19/1 * * * relax.sh
,8至19点每小时整点运行。
脚本功能:
- 在当前开启的所有虚拟终端(pts)上输出提示音,提示音频率由慢到快,最后用vlc播放音频文件“break.mp3”,并关闭屏幕;
- 脚本运行期间(约43秒),任一新打开的虚拟终端都会输出,无法正常工作,强迫你停止;
- 如果当前是16点,则用vlc播放眼保健操广播音eyes.f4v,这是我在网上找的老版本,80后的记忆;60s后关闭屏幕;
- 因为脚本是向pts输出,所以只对linux桌面的虚拟终端用户有效,如gnome-terminal;tty用户需修改脚本;
未解决的问题:
- 音频文件“break.mp3”内容是一句“Let's take a break, see you later.”。原计划是用TTS(text to speeh),但是装了festival运行报错(fragmentation fault),应该是程序的问题。于是就找了个online tts,提供mp3下载,暂时先这么用;
- vlc命令行指定音量的参数不知道是什么;
vlc播放完文件后进程一直在,不知道有没有自动关闭的参数;目前的解决办法是把vlc进程放到后台,sleep一段和音频长度相同的时间后kill $(pidof vlc)
;- 如果系统有其他声音正在输出,可能听不到音频。想法是将其它进程禁音,音频播放后再恢复。待实现;
- 播放音频后面的重定向语句“
< /dev/null &> /dev/null &
”不能通过赋给变量来做替换,有别的办法么?
Aug 15, 2016 更新:
Aug 18, 2016 更新:
- 加入自动关机,12点和19点开始5分钟倒计时,每分钟播报一次,最后10秒倒计时关机;
- Fedora 24下,必须在cron中用sudo shutdown,即使有权限使用shutdown。因此需要在visudo中加入一条NOPASSWD:/user/sbin/shutdown
- 更新代码;
Aug 19,2016更新:
- 用mplayer代替vlc,自动关闭,且启动时可以指定音量;
- 新增变量$play,取代之前的$vlcpara,通过判断mplayer是否安装以决定运行mplayer或vlc;
- vlc并不需要“
< /dev/null
”,但mplayer需要,否则无法后台运行,所以统一添加; - 让注释更好看;
- 提交至github;
- 更新代码;
Aug 23, 2016更新:
- abreak()里第一个for循环的表达式2,一直不明白为什么i>0&&j>0走到2.1就停了,甚至怀疑((...))里是否支持逻辑组合;最后发现,原来是一个逻辑错误,应该用||
完整代码如下:
#!/bin/bash
#
# dotr
#
# 0 8-19/1 * * * dotr
# A script for reminding you to AFK and have a little rest.
# Add to crontab so it will run per hour.
############### Variables ###############
hour=$(date +%H)
sdir=~/.local/sound
if [ -e /usr/bin/mplayer ]; then
play="mplayer -quiet -volume 100"
else
play="cvlc --quiet --play-and-exit"
fi
############### Functions ###############
# Get the list of /dev/pts/
function list(){
l=$(ls /dev/pts | grep "[0-9]")
}
# Ask you to take a break.
function abreak(){
# interval initialize to 2.5s, minus 0.1 every loop
#for ((i=2,j=5;i>0||j>0;j--))
for ((i=2,j=5;i+j>0;j--))
do
list
for a in $l
do
echo -e "\a""\nLet's take a break, see you later." > /dev/pts/$a
done
sleep $i.$j
if [ $j == 0 ]; then
j=10
i=$((i-1))
fi
# when interval reduces to 0.5s, do 20 times and exit
if [ $i == 0 -a $j == 5 ]; then
for ((k=20;k>0;k--))
do
list
for a in $l
do
echo -e "\a""\nLet's take a break, see you later." > /dev/pts/$a
done
sleep $i.$j
done
#kill $(pidof vlc) &> /dev/null
$play $sdir/break.mp3 < /dev/null &> /dev/null &
sleep 2.5
DISPLAY=:0 xset dpms force off
#sleep 2.3
#kill $(ps -C vlc | awk '/vlc/ {print $1}')
#kill $(pidof vlc)
exit
#i=0;j=0
fi
done
}
# Do some exercise.
function eyes(){
#kill $(pidof vlc) &> /dev/null
$play $sdir/eyes.f4v < /dev/null &> /dev/null &
sleep 60
DISPLAY=:0 xset dpms force off
#sleep 265
#kill $(ps -C vlc | awk '/vlc/ {print $1}')
#kill $(pidof vlc)
}
# Shutdown in 5 minutes.
function shutd () {
# 5 minutes countdown.
for i in $(ls $sdir | grep a.mp3 | sort -nr)
do
$play $sdir/$i < /dev/null &> /dev/null &
if [ ${i:0:2} -eq "60" ]; then
sleep 50
else
sleep 60
fi
done
# 10 seconds countdown.
for i in $(ls $sdir | grep b.mp3 | sort -nr)
do
$play $sdir/$i < /dev/null &> /dev/null
sleep 0.1
done
if [ $hour -eq 12 ]; then
$play $sdir/lunch.mp3 < /dev/null &> /dev/null
else
$play $sdir/night.mp3 < /dev/null &> /dev/null
fi
sudo shutdown now
}
############### Main Part ###############
if [[ $hour =~ ^1[29] ]] || [ "$1" == "s" ]; then
shutd
elif [ $hour == 16 -o "$1" == "e" ]; then
eyes
else
abreak
fi
Add new comment