# Asynchronous variant of sched. # The syntax is the same. # # TODO: would be better if we could use job handling directly # but the programming interface to that isn't great, so currently # it uses processes (though these will be in jobs if the monitor # option is set). emulate -L zsh setopt extendedglob zmodload -i zsh/datetime || return 1 integer -g ASCHED_JOB typeset -ga asched_processes local strtime proc integer now=$EPOCHSECONDS hhour hour mminute minute diff time i procwid local -a match mbegin mend # Use guesswork to decide whether the process has been run. for (( i = 1; i <= ${#asched_processes}; i++ )); do time=${${asched_processes[$i]##<-> #}%% *} if (( now > time )); then # it's all over asched_processes[$i]= fi done if [[ $1 = -(#b)(<->) ]]; then local killproc="${asched_processes[$match[1]]%% *}" if [[ -n $killproc ]]; then kill $killproc asched_processes[$match[1]]= else print -r "asched: no such asched job or time already past" fi elif (( $# == 0 )); then # the width of the length of the array, for padding... procwid=${#:-${#asched_processes}} for (( i = 1; i <= ${#asched_processes}; i++ )); do proc=${asched_processes[$i]} if [[ -n $proc ]]; then print "${(l.$procwid.)i} ${proc##<-> #<-> #}" fi done return 0 elif [[ $1 != (#b)(+|)(<->):(<->) || $# -lt 2 ]]; then print "Usage: asched [+]HH:MM job asched [ - ]" >&2 return 1 fi shift local job="$*" hhour=$match[2] mminute=$match[3] if [[ -n $match[1] ]]; then # relative (( diff = (hhour * 60 + mminute) * 60 )) else # absolute, so work out when now is. # assume today, so if it's in the past run job immediately. strftime -s hour %H $now strftime -s minute %M $now (( diff = ((hhour - hour) * 60 + mminute - minute) * 60 )) if (( diff < 0 )); then # do it in subshell since user expects this not to affect main shell (eval $job) return 0 fi fi (( ASCHED_JOB++ )) (( time = now + diff )) strftime -s strtime "%a %b %d %H:%M:%S" $time eval "(: asched job $ASCHED_JOB sleep $diff; $job) &" # Format: background task, Epoch time, string time, job name. # The last two are for human consumption. asched_processes[$ASCHED_JOB]="$! $time $strtime $job"