希望警报脚本在后台运行,但请接受用户输入以阻止它



我在http://milkteafuzz.com/j/2012/02/22/a-simple-bash-alarm-clock/上删除了一个非常简单但有效的警报脚本用户输入在终端运行时可能是3个参数之一:警报日期时间,警报声音文件或警报标题MSG显示。如果未读取输入,则脚本会提示用户使用默认声音文件和警报标题-MSG显示date for日期时间。

警报发出时,我有一个读取命令,提示用户按" Enter"键停止警报。

我想在运行后运行脚本,但仍允许用户停止警报(当然),但我似乎无法实现解决方案。

这是我拥有的ATM(简洁省略功能)。:

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 "nt33[1;36mOkay! Will alert you on:33[1;32m" $(date --date="$date")"33[0mn"
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 $'n33[1;33mHit Enter key to stop the alarm.33[0mn' 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 PID杀死每个MPG PID,虽然肯定不是很漂亮,但似乎奏效了。好东西,我用大胆的流式传输音乐,所以杀死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

尝试使用"屏幕"命令

在这里示意

我认为没有任何方法可以迫使呼叫壳将脚本带入前景。通常,您会使用fg手动执行此操作,按Enter,然后使用CRTL-Z将其放回后台。

如果警报是唯一的背景作业(或最新的)fg本身就足够了。如果没有,您可以看到jobs的背景过程的作业编号。向fg提供工作编号作为参数。

查看man bash的"工作控制"部分,以获取更多信息。

相关内容

  • 没有找到相关文章