我在http://milkteafuzz.com/j/2012/02/22/a-simple-bash-alarm-clock/找到一个非常简单但有效的警报脚本,以便在终端运行命令时接受用户输入,该终端可能是3个参数之一:警报日期时间,警报声音文件或警报标题 - 要显示的消息。如果没有读取输入,则脚本会使用默认声音文件和警报标题-msg提示用户输入警报的日期时间。
当闹钟响起时,我有一个读取命令,提示用户点击“Enter”键以停止闹钟。
我想让脚本在运行时在后台运行,但仍然允许用户停止警报(当然),但我似乎无法实现解决方案。
以下是我的内容(为了简洁省略了函数)。:
echo ""
#'if' user input $1 is supplied
if [[ -n "$1" ]] ; then
if [[ "$1" =~ [0-2]{0,1}[0-9][:]{1}[0-9]{1,2} ]] ; then #'if' input $1 matches date-time format
date="$1" #; echo "\$date: ${date}"
elif [[ "$1" =~ ^.*\.(mp3|ogg)$ ]] ; then #'if' input $1 has mp3/ogg ext
fChkFile "$1" #funct call
else #'else' it is assumed input $1 is alarm title-msg to display when alarm goes off
msg="$1" #; echo "\$msg: ${msg}"
fi
fi
#'if' user input $2 is supplied
if [[ -n "$2" ]] ; then
fInput23 "$2" #funct call
fi
#'if' user input $3 is supplied
if [[ -n "$3" ]] ; then
fInput23 "$3" #funct call
fi
if [[ -z "$date" ]] ; then #'if' date-format IS null then not detected from user input and so prompt user for one
printf "What time should the alarm sound? "
read date
if [[ -z "$date" ]] ; then #'if' "$date" IS still null then abort
notify-send "Aborting. A date-time format is required and none was detected."
exit 67
fi
fi
if [[ -z "$msg" ]] ; then #'if' title-message IS null then assign default
msg="The time has arrived to sit up and take notice..." #; echo "\$msg: ${msg}"
fi
if [[ -z "$sndF" ]] ; then #'if' sound file IS null then assign default
sndF="/media/multiMediaA_intHdA720Gb/music/theStrokes_isThisIt/07_lastNite.mp3" #; echo "\$sndF: ${sndF}"
fi
echo -e "\n\t\033[1;36mOkay! Will alert you on:\033[1;32m" $(date --date="$date")"\033[0m\n"
sleep $(( $(date --date="$date" +%s) - $(date +%s) ));
notify-send "$msg" -t 0
#while true; do
/usr/bin/mpg123 -q -l 0 "$sndF" &
sleep 1
read -ep $'\n\033[1;33mHit Enter key to stop the alarm.\033[0m\n' killAlm
#almPid=$(ps aux|grep "\/usr\/bin mpg123"|cut -d' ' -f3) #; echo "\$almPid: ${almPid}"
almPid=$(ps aux|grep "\/usr\/bin mpg123"|sed -r 's/^[^ \t]*[ \t]*([0-9]{3,5})[ \t]*.*$/\1/') #; echo "$almPid"
kill "$almPid"
#done
脚本运行正常且花花公子,但我真的不喜欢为每个警报集绑定终端的想法(我的记忆就像一个筛子,我倾向于在任何给定时间使用多个警报)。我如何运行脚本,接受输入(至少是日期时间var)然后在BG中运行,从而释放终端,但提示用户在一个人关闭时停止报警?
修改的: 使用屏幕可以正常工作,如下面的评论中所述。但由于某种原因,突然间(第一次,自尝试“屏幕”解决方案),挂起的mpg流程将无法清除,所以
kill "$almPid"
失败,因为它试图清除现在挂起的上一个进程。所以我添加了一个循环来循环通过所有mpg pids连续杀死每一个,虽然肯定不漂亮,似乎工作。好东西我用大胆的流媒体音乐,所以骑自行车杀死mpg pids不会破坏任何东西,除非当然有多个警报同时响起我猜。
#almPid=$(ps aux|grep "\/usr\/bin mpg123"|sed -r 's/^[^ \t]*[ \t]*([0-9]{3,5})[ \t]*.*$/\1/') #; echo "$almPid"
for p in $(ps aux|grep "\/usr\/bin mpg123"|sed -r 's/^[^ \t]*[ \t]*([0-9]{3,5})[ \t]*.*$/\1/') ; do
# echo "\$p: $p"
kill "$p"
done
答案 0 :(得分:2)
尝试使用"屏幕"命令
答案 1 :(得分:0)
我认为没有办法强制调用shell将脚本带到前台。通常您可以使用fg
手动执行此操作,按Enter键,然后使用CRTL-Z将其重新置于后台。
如果警报是唯一的后台作业(或最近的作业)fg
本身就足够了。如果不是,您可以使用jobs
查看后台进程的作业编号。将作业号作为fg
的参数提供。
查看man bash
的“JOB CONTROL”部分以获取更多信息。