作为练习,我几个月前写了一个快速且肮脏的bash脚本来设置无线电警报。它将cron / at-job设置为在指定时间开始流式传输互联网广播(我使用mplayer),并将作业ID记录在文件中以方便撤消。但是,按照目前的情况,关闭正在运行的警报的逻辑仅仅是杀死最近几个mplayer实例。如果您在警报响起时正在观看视频,或者正在运行转换音频或视频文件的批处理作业,则可能存在问题。
所以我想我将创建一个指定的虚拟用户来运行此脚本,并且不要杀死所有最新的mplayer实例,而要杀死该用户调用的所有实例,而不是杀死它们。因此,我创建了一个用户radiowecker
,并使用sudo -u radiowecker /var/lib/radiowecker/wecker $1
调用了脚本。但是,这似乎没有完成该工作:尽管at
-job确实显示为radiowecker
,但它产生的mplayer实例却保存在我的UID下。如何确保子进程也以radiowecker
的形式提交?
if [ $2 ];
then stream="$2"
else stream=http://mp3stream1.apasf.apa.at:8000;
fi
if [ $1 ]; then
# with argument, set new radio alarm using 'at' and log the at-job-id
remove_log_when_playing="rm ~/.local/bin/weckerlogs/${*} "
play_radio="mplayer $stream -cache 1024"
and="&&"
show_running="touch ~/.local/bin/alarm_running"
printf "$remove_log_when_playing && $show_running && $play_radio" | at "${*}" \
&& echo $(atq | sort -nr | { read first last ; echo $first ; }) >> ~/.local/bin/weckerlogs/"${*}"
else
if [[ $(pgrep mplayer) && -e ~/.local/bin/alarm_running ]]; then
rm ~/.local/bin/alarm_running
# turn off running mplayer, assumed to be called from an earlier alarm
for i in 0 1; do
for id in $(pgrep mplayer)
do WECKER=$id
done
kill $WECKER
done
else
# turning off an alarm in the future has its own tool
echo "No active mplayer instances found."
echo "To turn off a future alarm, instead"
echo "use 'wecker-aus' <time>!"
echo "Currently set alarms:"
ls ~/.local/bin/weckerlogs/
fi
fi
关闭将来的警报:
#/bin/bash
log=~/.local/bin/weckerlogs/"${*}"
atrm $(cat "$log")
rm "$log"