zoukankan      html  css  js  c++  java
  • Shell脚本:(delayexec)Cygwin下调用schtasks创建Windows任务计划,实现延迟或定时执行某一命令

    脚本用法:

    /v/bin/delayexec
    
            创建Windows任务计划,延迟或定时执行Cygwin下某命令.
            注:本脚本创建的任务计划仅执行一次,不会重复调用,如果需要周期性反复执行的命令,请手动创建任务计划或使用`schtasks`命令来创建;
    
    Usage:
            delayexec delaytime-Seconds|time-clock(时:分:秒) command argument1 argument2 ...
    Example1:
            delayexec 3600 tplink
            - 延迟3600秒(1小时)执行tplink
    Example2:
            delayexec 05:30 recordlive-bilibili 7200
            - 今天或次日5点半(取决于现在时刻早于还是晚于指定的时间)执行recordlive-bilibili录制视频两小时
    Example3:
            delayexec ++07:30 killpm tplink
            - 两天后的7点半退出tplink进程,+号指定延迟的天数,+可叠加使用,如+++代表当前日期后延3天
    
    

    代码如下:

    #!/bin/bash
    #Windows计划任务cron脚本,通过任务计划调用Cygwin执行某命令
    ## Example:
    ## 1. delayexec 3600 tplink  #延迟3600秒(1小时)运行tplink
    ## 2. delayexec 05:30 tplink  #定时5点半运行tplink,自动识别日期,当前时刻早于指定时间,则当天执行,当前时刻晚于指定时间,则次日执行
    ## 2. delayexec ++07:30 tplink  #两天后的七点半运行命令tplink,此模式用以显式指定日期,一个+号代表延期一天,可以重复叠加,+代表1天后,+++代表3天后
    SCRIPTPATH=$(realpath $0)
    
    display_usage() {
    	echo -e "$SCRIPTPATH
    "
        echo -e "	创建Windows任务计划,延迟或定时执行Cygwin下某命令."
    	echo -e "	注:本脚本创建的任务计划仅执行一次,不会重复调用,如果需要周期性反复执行的命令,请手动创建任务计划或使用\`schtasks\`命令来创建;"
        echo -e "
    Usage:
    	delayexec delaytime-Seconds|time-clock(时:分:秒) command argument1 argument2 ..."
    	echo -e "Example1:
    	delayexec 3600 tplink"
    	echo -e "	- 延迟3600秒(1小时)执行tplink"
    	echo -e "Example2:
    	delayexec 05:30 recordlive-bilibili 7200"
    	echo -e "	- 今天或次日5点半(取决于现在时刻早于还是晚于指定的时间)执行recordlive-bilibili录制视频两小时"
    	echo -e "Example3:
    	delayexec ++07:30 killpm tplink"
    	echo -e "	- 两天后的7点半退出tplink进程,+号指定延迟的天数,+可叠加使用,如+++代表当前日期后延3天"
    }
    # if less than two arguments supplied, display usage
    if [  $# -lt 1 ]
    then
        display_usage
        exit 1
    fi
    
    # check whether user had supplied -h or --help . If yes display usage
    if [[ ( $* == "--help") ||  $* == "-h" ]]
    then
        display_usage
        exit 0
    fi
    
    getDelayExecTime() {
    	# 参数$1传递需要延迟执行任务计划的时间,单位为秒
    	#local updateTime=$(date -d "1970-01-01 UTC ${1} seconds +3 minutes" +'%Y-%m-%dT%H:%M:%S')
    	local updateTime=$(date -d "+${1} Seconds" +'%Y-%m-%dT%H:%M:%S')
    	echo "$updateTime"
    }
    
    getClockExecTime() {
    	# 参数$1传递执行任务计划的准确时刻,示例:14:25
    	 case $1 in
    		0)
    		local executeTime=$(date -d "+1day $2" +'%Y-%m-%dT%H:%M:%S')
    		;;
    	    *)
    		local executeTime=$(date -d "$2" +'%Y-%m-%dT%H:%M:%S')
    		;;
    	 esac
    	 echo "$executeTime"
    }
    
    
    #说明:以下为什么要用两个模板文件,为什么要先导出XML再更改,主要考虑是为了更好的兼容性,比如更换电脑后,用户Sid改变导致任务计划不能按预期效果执行,此故障到底会不会发生未经严格测试,仅此以防万一
    schTasksXML="/v/reg-tpl/update-delayexec-schtasks.xml"
    schTasksXMLInitFile="/v/reg-tpl/update-delayexec-schtasks-init.xml"
    
    #默认延迟时间:3600秒
    delayTimeSec=3600
    #执行命令的时间:
    executeTime=-1
    
    #脚本 $1 供外部传递延迟时间,参数类型正整数,单位为秒
    if [ ! -z "$1" ]
    then	
    	expr $1 + 0 &>/dev/null
    	if [ $? -eq 0 ]
    	then
    		delayTimeSec=$1
    		shift
    	elif [[ "$1" =~ ^(++)?[0-9]{1,2}:[0-9]{2}(:[0-9]{2})?$ ]]
    	then
    		delayDays=0
    		#处理时间参数传递+号的情况,+号可重复叠加使用,如:++00:30 表示两天后的夜里12点半。
    		while read -n 1 char ; do
    			if [ "$char" != "+" ]
    			then
    				break
    			fi
    			let delayDays+=1
    		done <<<"$1"
    		if [ $delayDays -eq 0 ]
    		then
    			[ $(date +'%s') -ge $(date -d "$1" +'%s') ]
    			executeTime=$(getClockExecTime $? "$1")
    			delayTimeSec=-1
    		else
    			timeExpression="+ ${delayDays} days ${1//+/}"
    			executeTime=$(getClockExecTime 1 "$timeExpression")
    			delayTimeSec=-1
    		fi
    		shift
    	fi
    fi
    
    #预备执行的命令:
    prepareExecCommand="$*"
    
    [ -z "$prepareExecCommand" ] && {
    	echo "待执行命令为空,脚本退出..."
    	exit 0
    }
    
    #XML使用的计划任务名称:
    schtasksTitle="${*////_}"
    #schtasksTitle="$1"
    
    [ "$executeTime" = "-1" ] && executeTime=$(getDelayExecTime $delayTimeSec)
    
    [ $delayTimeSec -ne -1 ] && echo "延迟 $delayTimeSec 秒后执行命令:${prepareExecCommand}"
    echo "执行时间:$(date -d "${executeTime}" +'%Y-%m-%d %H:%M:%S')"
    #exit 0  #Test:中断
    
    schtasksURI='\Cygwin自用\定时执行命令:'"${schtasksTitle}"
    
    #导出最新的定时执行命令的任务计划模板:
    gsudo SCHTASKS /Query /TN "${schtasksURI//\\/\}" /XML ONE >$(cygpath -aw "$schTasksXML") 2>/dev/null
    
    #如果XML文件大小为零,即计划任务管理器没有该任务,则从预先准备的最原始的XML文件读取任务计划信息:
    if [ "$(stat -c '%s' $schTasksXML)" == "0" ]
    then
    	#echo "指定的任务计划不存在!"
    	#exit 0
    	schTasksXML=$schTasksXMLInitFile
    fi
    
    #替换任务唤醒时间为指定时间,并去掉禁用任务的标识(如果任务被禁用的话):
    awk -i inplace '/<URI>/{getline;print "<URI>'"${schtasksURI}"'</URI>"}/StartBoundary/{getline;print "	<StartBoundary>'${executeTime}'</StartBoundary>"}/<Enabled>false/{getline;}/<Arguments>/{getline;print "	<Arguments>'"${prepareExecCommand}"'</Arguments>"}{print}' $schTasksXML
    #cat $schTasksXML
    #导入XML文件到计划任务:
    gsudo SCHTASKS /Create /F /XML $(cygpath -aw "$schTasksXML") /TN "${schtasksURI//\\/\}"
    
    echo -e "Done..."
    
    

    帮助信息截图:

    运行结果截图:


    附件:XML文件 update-delayexec-schtasks-init.xml 之模板代码如下:

    <?xml version="1.0" encoding="UTF-16"?>
    
    <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
    
      <RegistrationInfo>
    
        <Date>2021-09-29T14:45:34.6728472</Date>
    
        <Author>DESKTOP-ENTJJOKAdministrator</Author>
    
    <URI>Cygwin自用定时执行命令:tplink</URI>
      </RegistrationInfo>
    
      <Principals>
    
        <Principal id="Author">
    
          <UserId>S-1-5-21-1929780610-3846960160-3848736843-500</UserId>
    
          <LogonType>InteractiveToken</LogonType>
    
        </Principal>
    
      </Principals>
    
      <Settings>
    
        <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    
        <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    
        <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    
        <IdleSettings>
    
          <StopOnIdleEnd>true</StopOnIdleEnd>
    
          <RestartOnIdle>false</RestartOnIdle>
    
        </IdleSettings>
    
      </Settings>
    
      <Triggers>
    
        <TimeTrigger>
    
    	<StartBoundary>2021-10-19T12:00:00</StartBoundary>
        </TimeTrigger>
    
      </Triggers>
    
      <Actions Context="Author">
    
        <Exec>
    
          <Command>D:Extra_bincygwin-hide.exe</Command>
    
    	<Arguments>tplink</Arguments>
        </Exec>
    
      </Actions>
    
    </Task>
    
    

    本文来自博客园,作者:晴云孤魂,转载请注明原文链接:https://www.cnblogs.com/cnhack/p/15423136.html

  • 相关阅读:
    视觉里程计VO-直接法
    Linux安装libcholmod-dev找不到的解决方法
    Levenberg-Marquadt Method
    Gauss-Newton Method
    CMake
    方差 标准差 协方差
    SFM
    矩阵分解
    kvm学习笔记
    python学习笔记
  • 原文地址:https://www.cnblogs.com/cnhack/p/15423136.html
Copyright © 2011-2022 走看看