新增、删除、查询任务计划
#wintask-query #根据任务名称关键词查询Windows计划任务 #wintask-del #根据任务名称关键词删除Windows计划任务,也可以传递计划任务完整路径 #wintask-run #根据任务名称关键词立即运行Windows计划任务 #wintask-enable #根据任务名称关键词启用Windows计划任务 #wintask-disable #根据任务名称关键词禁用Windows计划任务 wintask-query(){ # 根据任务名称关键词查询Windows计划任务 # Usage:wintask-query xxx #———————————————————————————————————————————————————————————————————————————————————————————————————— #gsudo schtasks.exe /Query /V /FO LIST|awk 'BEGIN{IGNORECASE = 1;}/TaskName:.*'$1'*/,/^\s+$/{print}' #修复正则匹配@20221226: #1、精确匹配多个相似任务名:eg:stop-potplayer OR stop-potplayer2 #2、适配查询参数中带路径分隔符反斜杠的情况(\) gsudo schtasks.exe /Query /V /FO LIST|awk 'BEGIN{IGNORECASE = 1;}/TaskName:.*?'"${1//\\/\\\\}"'.*?$/,/^\s+$/{print}' } wintask-del(){ # 根据任务名称关键词删除Windows计划任务,也可以传递计划任务完整路径 # Usage:wintask-del xxx # eg:wintask-del stop-potplayer2 #关键字搜索 # wintask-del '\Cygwin自用\定时执行命令:stop-potplayer2' #任务完整路径 if [ $# -ge 1 ] && [[ "$1" != "" ]]; then if [[ $1 =~ ^\\ ]]; then local taskName=$1 else #local taskName=$(wintask-query "$1"|dos2unix|awk '/TaskName/{printf $2;exit}') local taskNames="$(wintask-query $1|dos2unix|awk '/TaskName/{sub($1" ","");sub(/^[ \t]*/,"");print $0}')" #适配关键词匹配到多个任务的情况 fi [ -z "${taskNames}" ] && local taskNames=("${taskName//\\/\\\\}") #local taskCount=(${taskNames}) declare -a taskCount while read -u 0 taskName do local taskCount=("${taskCount[@]}" "$taskName") done<<<"$taskNames" if [ ${#taskCount[*]} -gt 1 ]; then echo -e "警惕操作:\"$1\" 匹配到多个任务!(${#taskCount[*]})" #echo "${taskCount[*]}"|sed -r 's/ /\n/g' echo "$taskNames" read -p "是否继续操作?(y/n,yes/no),默认为no: " delcontinue if [[ ! "${delcontinue,,}" == "y" && ! "${delcontinue,,}" == "yes" ]]; then echo "退出操作..." && return fi elif [ ${#taskCount[*]} -eq 1 ]; then read -p "是否确认要删除任务 ${taskCount[0]}?(y/n,yes/no),默认为no: " delcontinue if [[ ! "${delcontinue,,}" == "y" && ! "${delcontinue,,}" == "yes" ]]; then echo "退出操作..." && return fi fi #for taskName in `read -u 0` while read -u 0 taskName do #echo "Do => $taskName" gsudo schtasks.exe /Delete /TN "$taskName" /F done<<<"${taskNames//\\/\\\\}" else echo -e "Need Paramter: Task Name KeyWord or Full Path!" fi } wintask-run(){ # 根据任务名称关键词立即运行Windows计划任务; # Usage:wintask-run xxx # 可传递具体任务路径或任务关键字进行搜索; # Example: # wintask-run '\Cygwin自用\语音整点报时' || wintask-run '\Cygwin自用\定时执行命令:alarm' # OR # wintask-run 语音整点报时 if [ $# -ge 1 ] && [[ "$1" != "" ]]; then if [[ $1 =~ ^\\ ]]; then local taskName=$1 else #local taskName=$(wintask-query $1|dos2unix|awk '/TaskName/{printf $2;exit}') local taskNames="$(wintask-query $1|dos2unix|awk '/TaskName/{sub($1" ","");sub(/^[ \t]*/,"");print $0}')" #适配关键词匹配到多个任务的情况 fi [ -z "${taskNames[*]}" ] && local taskNames=("$taskName") declare -a taskCount while read -u 0 taskName do local taskCount=("${taskCount[@]}" "$taskName") done<<<"$taskNames" #local taskCount=(${taskNames[@]}) if [ ${#taskCount[*]} -gt 1 ]; then echo -e "提示:\"$1\" 匹配到多个任务!(${#taskCount[*]})" #echo "${taskCount[*]}"|sed -r 's/ /\n/g' echo "$taskNames"|awk '{print NR" ):"$0;}' while :; do read -p "请输入序号选择你要执行的任务(输入 all/a 运行全部任务,q 或 0 退出操作): " taskChoose if [ -z "$taskChoose" ] || [[ "${taskChoose,,}" == "q" || "${taskChoose,,}" == "0" ]];then echo "退出操作..." && return elif expr "$taskChoose" + 0 &>/dev/null; then local taskName=$(echo "$taskNames"|awk 'NR=='$taskChoose'{print;exit}' 2>/dev/null) [ ! -z "$taskName" ] && { echo "运行任务:$taskName" gsudo schtasks.exe /Run /TN "$taskName" return } || echo "序号选择无效,请重新选择!" elif [[ "${taskChoose,,}" == "all" || "${taskChoose,,}" == "a" ]]; then echo "运行全部任务:" && break else echo "无效选择,退出操作..." && return fi done fi #for taskName in $taskNames while read taskName do #echo "Do => $taskName" gsudo schtasks.exe /Run /TN "$taskName" done<<<"${taskNames//\\/\\\\}" else echo -e "Need Paramter: Task Name KeyWord or Full Path!" fi } wintask-enable(){ # 根据任务名称关键词启用Windows计划任务 # Usage:wintask-enable xxx if [ $# -ge 1 ] && [[ "$1" != "" ]]; then if [[ $1 =~ ^\\ ]]; then local taskName=$1 else #local taskName=$(wintask-query $1|dos2unix|awk '/TaskName/{printf $2;exit}') #local taskNames=$(wintask-query $1|dos2unix|awk '/TaskName/{gsub(/TaskName:[\t| ]+/,"");print}') #兼容计划任务名包含空格的情况 local taskNames=$(wintask-query $1|dos2unix|awk '/TaskName/{gsub(/TaskName:[\t| ]+/,"");taskname=$0}\ /Scheduled Task State/{if($NF=="Disabled"){printtaskname="true"}}\ /Repeat: Stop If Still Running/{if(printtaskname=="true"){\ print taskname;\ printtaskname="";\ }}') #仅搜索包含关键词且处于禁用状态的任务 fi [ -z "$taskNames" ] && taskNames="$taskName" [ -z "$taskNames" ] && echo "“$1” 没有找到任何匹配的任务!" && return [ $(echo "$taskNames"|wc -l) -gt 1 ] && { echo "$taskNames" read -p "“$1” 匹配到多于一个的计划任务,是否批量启用以上任务?"$'\n'"> " goContinue [[ ! "${goContinue,,}" == "yes" && ! "${goContinue,,}" == "y" ]] && echo "取消操作..." && return } OLD_IFS=$IFS IFS=$(echo -e "\n") #for taskName in $taskNames while read taskName do #echo "操作任务:=> $taskName" gsudo schtasks.exe /CHANGE /ENABLE /TN "$taskName" done<<<"${taskNames//\\/\\\\}" IFS=$OLD_IFS else echo -e "Need Paramter: Task Name KeyWord or Full Path!" fi } _wintask-disable-for-select(){ # 根据任务名称关键词禁用Windows计划任务 # 此函数专供SSH远程链接会话序号选择使用(因手机上不好输入或者复制计划任务的网址途径) if [ $# -ge 1 ] && [[ "$1" != "" ]]; then if [[ $1 =~ ^\\ ]]; then local taskName=$1 else local taskNames=$(wintask-query $1|dos2unix|awk '/TaskName/{gsub(/TaskName:[\t| ]+/,"");print}') #兼容计划任务名包含空格的情况 fi [ -z "$taskNames" ] && taskNames="$taskName" echo "$taskNames"|awk '{printf "%2d):%s\n",NR,$0}' declare chooseTask while [ -z "$chooseTask" ]; do read -p "请输入序号选择你要禁用的计划任务(0/q:退出,p/l:再次打印列表):"$'\n'"> " chooseTask [ -z "$chooseTask" ] && echo "退出操作..." && return [[ "$chooseTask" == "0" || "${chooseTask,,}" == "q" ]] && echo "退出操作..." && return [[ "${chooseTask,,}" == "p" || "${chooseTask,,}" == "l" ]] && { echo "$taskNames"|awk '{printf "%2d):%s\n",NR,$0}' chooseTask="" && continue } local taskName=$(echo "$taskNames"|sed -n "${chooseTask}p" 2>/dev/null) [ ! -z "$taskName" ] && break || { echo "选择无效,请重新选择!" chooseTask="" } done #echo "操作任务=>: $taskName" SSH_CONNECTION="" wintask-disable "$taskName" else echo -e "Need Paramter: Task Name KeyWord or Full Path!" fi } wintask-disable(){ # 根据任务名称关键词禁用Windows计划任务 # Usage:wintask-disable xxx declare taskName declare taskNames if [ $# -ge 1 ] && [[ "$1" != "" ]]; then if [ ! -z "$SSH_CONNECTION" ];then print_color 3 "当前通过ssh远程连接,提供序号选择列表:" _wintask-disable-for-select "$@" return fi if [[ $1 =~ ^\\ ]]; then local taskName=$1 else #local taskName=$(wintask-query $1|dos2unix|awk '/TaskName/{printf $2;exit}') #local taskNames=$(wintask-query $1|dos2unix|awk '/TaskName/{print $2}') #适配关键词匹配到多个任务的情况 local taskNames=$(wintask-query $1|dos2unix|awk '/TaskName/{gsub(/TaskName:[\t| ]+/,"");print}') #兼容计划任务名包含空格的情况 fi [ -z "$taskNames" ] && taskNames="$taskName" [ -z "$taskNames" ] && echo "“$1” 没有找到任何匹配的任务!" && return [ $(echo "$taskNames"|wc -l) -gt 1 ] && { echo "$taskNames" read -p "“$1” 匹配到多于一个的计划任务,是否批量禁用以上任务?"$'\n'"> " goContinue [[ ! "${goContinue,,}" == "yes" && ! "${goContinue,,}" == "y" ]] && echo "取消操作..." && return } OLD_IFS=$IFS IFS=$(echo -e "\n") #for taskName in $taskNames while read taskName do #echo "操作任务=>: $taskName" gsudo schtasks.exe /CHANGE /DISABLE /TN "$taskName" done<<<"${taskNames//\\/\\\\}" IFS=$OLD_IFS else echo -e "Need Paramter: Task Name KeyWord or Full Path!" fi }
20230223代码有完善更新,最新代码请查阅Gitee源码仓库:
https://gitee.com/hexiyou/shell-scripts/blob/master/wintask-funcs.sh
二次包装函数:
list-schtasks 、 wintasks、findtasks列出查询任务计划:
list-schtasks() { ## 在终端列出所有的Windows任务计划; OLD_IFS=$IFS IFS=$(echo -e "\n") local apppath="schtasks" local schbakpath='\Cygwin自用\' if [ "$(type -t $apppath)" == "file" ];then if [ ! -z "$1" ];then #$1可指定要查询的路径,也可以指定显示任务的XML if [[ "${1,,}" == "-a" || "${1,,}" == "all" || "${1,,}" == "--all" ]]; then local schbakpath='\' echo -e "查询本机所有任务计划..." elif [[ "${1,,}" == "--xml" ]];then gsudo schtasks /Query /TN "$schbakpath" /XML ONE return else local schbakpath="$1" fi fi #gsudo schtasks /Query /TN "$schbakpath" /XML ONE #TODO:后期使用 xmlstarlet 解析更复杂的XML信息; gsudo schtasks /Query /TN "$schbakpath" /XML ONE|awk -F "[><]" '\ /<URI>/{printf $3"\t";needPrintTime=true};\ /<Enabled>/{if($3=="false"){printf "\t\033[31m【禁用】\033[0m";}}\ /* StartBoundary有多个定时器时仅显示第一个 */ /<StartBoundary>/{printf "\t"$3};\ /<BootTrigger>/{printf "\t系统启动时"};\ /<Delay>/{printf "\t延迟"$3};\ /<Interval>/{printf "\t"$3"@"};\ /<Duration>/{printf $3};\ /<DaysInterval>/{printf "\t每天"};\ /<Command>/{printf "\t||"$3" ";getline;if(match($0,/Arguments/)){printf $3"\n";}else{printf "\n"}};\ ' else print_color 9 "program not found!\npath:${apppath//\\/\\\\} " fi IFS=$OLD_IFS } # 此函数转为使用alias调用 findtasks实现更佳,更符合语义,故先注释掉 #findalarm() { # #查找已设置的任务闹钟 # eval list-schtasks|grep alarm #} findtasks() { ## 根据名称或命令行参数查找任务计划 # --- 默认仅查找启用的任务,可附加参数查找禁用的任务 # eg: # findtasks 录制 --disable # findtasks 录制 --enable # findtasks 录制 --all #同时查找禁用和启用的任务 local name="$1" [ -z "$name" ] && print_color 40 "\$1 请传递要查找的关键字!" && return shift 1 #eval list-schtasks|grep "$name" eval wintasks "$@"|grep "$name" } alias findalarm='findtasks alarm' alias findrecordlive='findtasks recordlive' alias findtasksonce='findtasks "||" --once'
wintasks:按状态仅列出启用或被禁用的计划任务
wintasks() { #按状态仅列出启用或被禁用的服务 #See Also:剔除$@最后一个参数:https://www.igiftidea.com/article/13591115462.html if [[ "${@:$#}" == "--disable" ]];then #unset ${#_args[@]}-1 #set -- "$@" #set -- "${@:0:$#}" set -- "${@:1:$(($#-1))}" # <-- 删除最后一个参数 list-schtasks "$@"|grep '禁用' elif [ $# -eq 0 ] || [[ "${@:$#}" == "--enable" || "${@:$#}" == "--active" ]];then [ $# -gt 0 ] && set -- "${@:1:$#-1}" # 防止参数个数为零时报错:-bash: $#-1: 子串表达式 < 0 list-schtasks "$@"|grep -v '禁用' # <--- 激活的计划任务 elif [[ "${@:$#}" == "--all" ]];then #列出所有状态的任务(包含禁用或启用!) [ $# -gt 0 ] && set -- "${@:1:$#-1}" list-schtasks "$@" elif [[ "${@:$#}" == "--once" ]];then #列出仅执行一次的任务(排除需要每天执行的任务) [ $# -gt 0 ] && set -- "${@:1:$#-1}" list-schtasks "$@"|grep -v '每天' elif [[ "${@:$#}" == "--disable" ]];then #仅列出已禁用的任务 [ $# -gt 0 ] && set -- "${@:1:$#-1}" list-schtasks "$@"|grep '禁用' else list-schtasks "$@" fi }
标签:schtasks,wintask,Windows,taskNames,WSL,echo,任务,&&,taskName From: https://www.cnblogs.com/pythonClub/p/17782311.html