脚本不间断监控notepad.exe进程是否执行,若停止,则自动重启该进程,程序如下:
1 @echo off 2 3 set _task = notepad.exe 4 set _svr = c:\windows\notepad.exe 5 set _des = start.bat 6 7 :checkService 8 for /f "tokens=5" %%n in ('qprocess.exe ^| find "%_task%" ') do ( 9 if %%n==%_task% (goto checkMessage) else goto restartService 10 ) 11 12 :restartService 13 echo %time% 14 echo ********程序开始启动******** 15 echo 程序重新启动于 %time% ,请检查系统日志 >> restart_service.txt 16 echo start %_svr% > %_des% 17 echo exit >> %_des% 18 start %_des% 19 REM set /p=.<nul 不换行在屏幕输出.... 20 set /p=.<nul 21 for /L %%i in (1 1 10) do set /p a=.<nul & ping.exe /n 2 127.0.0.1>nul 22 echo . 23 del %_des% /Q 24 echo ********程序启动完成******** 25 goto checkService 26 27 28 :checkMessage 29 echo %time% 程序运行正常,5秒后继续检查.. 30 ping localhost -n 5 31 goto checkService
程序中涉及知识点:
1. for 用法
@echo off for /f %%i in (test.txt) do echo %%i pause
for 循环依次处理每个元素,直到所有的元素都被处理为止。只不过在for /f语句中,这里的元素是指文件中的每一行,也就是说,for /f 语句是以行为单位处理文本文件的
@echo off for /f "delims=," %%i in (test.txt) do echo %%i pause
"delims=,",它的含义是:以逗号作为被处理的字符串的分隔符号。在批处理中,指定分隔符号的方法是:添加一个形如 "delims=符号列表" 的开关,这样,被处理的每行字符串都会被符号列表中罗列出来的符号切分开来。需要注意的是:如果没有指定"delims=符号列表"这个开关,那么,for /f 语句默认以空格键或跳格键作为分隔符号。
@echo off for /f "delims=.," %%i in (test.txt) do echo %%i pause
逐行读取test.txt中的内容,以点号和逗号切分每一行的内容(不存在点号和逗号的行,则不再切分,为了描述的方便,我们把被点号或逗号切分的一个一个的字符串片段,称之为节),然后,for /f 会提取第一节的内容作为最终结果,显示在屏幕上。需要注意的是,在这里,所有行的字符串被切分成了两个以上的节,但是,代码只会提取第一节字符串的内容,因为 for /f 语句默认只提取第一节的符串。
@echo off for /f "delims=, tokens=3" %%i in (test.txt) do echo %%i pause
tokens= 后面一般跟的是数字,如 tokens=2,也可以跟多个,但是每个数字之间用逗号分隔,如 tokens=3,5,8,它们的含义分别是:提取第2节字符串、提取第3、第5和第8节字符串。注意,这里所说的“节”,是由 delims= 这一开关划分的,它的内容并不是一成不变的。如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,第一个数字指代的内容用第一个形式变量%%i来接收,第二个数字指代的内容用第二个形式变量%%j来接收,第三个数字指代的内容用第三个形式变量%%k来接收……第N个数字指代的内容用第N个形式变量来接收,其中,形式变量遵循字母的排序,第N个形式变量具体是什么符号,由第一个形式变量来决定:如果第一个形式变量是%%i,那么,第二个形式变量就是%%j;如果第一个形式变量用的是%%x,那么,第二个 形式变量就是%%y。
@echo off for /f "skip=2" %%i in (test.txt) do echo %%i pause
很多时候,有用的信息并不是贯穿文本内容的始终,而是位于第N行之后的行内,为了提高文本处理的效率,或者不受多余信息的干扰,for /f 允许你跳过这些无用的行,直接从第N+1行开始处理,这个时候,就需要使用参数 skip=n,其中,n是一个正整数,表示要跳过的行数。上面代码将跳过头两行内容,从第3行起显示test.txt中的信息
@echo off for /f "eol=;" %%i in (test.txt) do echo %%i pause
eol= 的准确含义是:忽略以指定字符打头的行
for /f %%i in (文件名) do (……) for /f %%i in ('命令语句') do (……) for /f %%i in ("字符串") do (……)
for /f "usebackq" %%i in ("文件名") do (……)
for /f "usebackq" %%i in (`命令语句`) do (……)
for /f "usebackq" %%i in ('字符串') do (……)
1. 当你希望读取文本文件中的内容的话,第一个括号中不用任何符号包裹,应该使用的是第1条语句;例如:你想显示test.txt中的内容,那么,就使用 for /f %%i in (test.txt) do echo %%i;
2. 当你读取的是命令语句执行结果中的内容的话,第一个括号中的命令语句必须使用单引号包裹,应该使用的是第2条语句;例如:你想显示当前目录下文件名中含有test字符串的文本文件的时候,应该使用 for /f %%i in ('dir /a-d /b *test*.txt') do echo %%i 这样的语句;
3. 当你要处理的是一个字符串的时候,第一个括号中的内容必须用双引号括起来, 应该是用的是第3条语句;例如:当你想把bbs.bathome.net这串字符中的点号换为短横线并显示出来的话,可以使用 for /f "delims=. tokens=1-3" %%i in ("bbs.bathome.net") do echo %%i-%%j-%%k 这样的语句
2. set
set的主要作用是赋值
2.1 set /p a=请输入你的姓名
先显示"请输入你的姓名",再接受用户输入的内容,以回车表示结束,赋值给变量a
2.2 set /p a=promptstring<1.txt
先显示promptstring,再把"<"管道号右边的1.txt文件中从第一个字符开始直到碰到回车符的内容赋值给变量a (通常表现为第一行)。
2.3 set /p a=promptstring<nul
先显示promptstring,再把"<"管道号右边nul中内容赋值给变量a ,不用用户按回车就结束语句。因nul是空设备,故没有内容可赋值,变量a仍属未定义。
因为在接受用户输入前可先显示promptstring,故此set还可当作显示命令用(仅作为显示命令使用时,可省略变量a)
2.4 set /p =promptstring
显示promptstring,再接受用户输入的内容,以回车表示结束。如用户直接按回车则仅显示promptstring。(赋值给空变量,赋值意义已丧失,仅作显示之用,需用户按回车键结束语句,无多大实际用途)
2.5 set /p =promptstring<1.txt
先显示promptstring,再把"<"管道号右边的1.txt文件中从第一个字符开始直到碰到回车符的内容赋值给空变量(无实际用途)
2.6 set /p =promptstring<nul
先显示promptstring,再把"<"管道号右边nul中内容赋值给空变量,不用用户按回车就结束语句,实际中常用这个句式作为显示语句。因显示promptstring后光标不换行,故实际中这个句式用到很多。如2楼所述,还有光标退格等。
3. if
在CMD使用IF /?打开IF的系统帮助(自己看我就不全部列出来了),我们会发现IF有3种基本的用法!
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
NOT 把NOT理解为C/C++中的取反操作符,然后就可以理解为C/C++中的条件表达式执行
ERRORLEVEL number 如果最后运行的程序返回一个等于或大于指定数字的退出编码,指定条件为true。
string1==string2 如果指定的文字字符串匹配,指定条件为 true,批处理中只有==没有!=,可以用NOT 条件表达式替代。
EXIST filename 如果指定的文件名存在,指定条件为 true。
command 如果符合条件,指定要执行的命令。如果指定的条件为 FALSE,命令后可跟一个执行 ELSE关键字后的命令的 ELSE 命令。
ELSE 子句必须出现在同一行上的IF 之后
1 @echo off 2 Setlocal enabledelayedexpansion 3 ::CODER BY dsw POWERD BY iBAT 4 set file="C:\abc.bat" 5 if exist %file% ( ::注意这里else后的空格 6 echo file is exists 7 )else ( ::注意这里else要和if的子句在同一行,并且else后要有空格 8 echo file is not exists 9 ) 10 pause
第一种用法:IF [NOT] ERRORLEVEL number command
这个用法的基本做用是判断上一条命令执行结果的代码,以决定下一个步骤.一般上一条命令的执行结果代码只有两结果,"成功"用0表示 "失败"用1表示.
@echo off Setlocal enabledelayedexpansion ::CODER BY dsw POWERD BY iBAT copy C:\abc.bat E:\ if %ERRORLEVEl% == 0 ( echo operation succ %ERRORLEVEl% )else ( echo operation fail %ERRORLEVEl% ) pause @echo off Setlocal enabledelayedexpansion ::CODER BY dsw POWERD BY iBAT set /p var=随便输入一个命令 %var% echo errorlevel is %ERRORLEVEL% if NOT %ERRORLEVEL% == 0 ( echo !var!执行失败 ) else ( echo !var!执行成功 ) pause
%ERRORLEVEL% 这是个系统变量,返回上条命令的执行结果代码! "成功"用0表示,"失败"用1表示.一般上一条命令的执行结果代码只有两结果,当然有的操作还有其他参数,这只是一般的情况。实际上,errorlevel返回值可以在0~255之间,比如,xcopy默认的errorlevel值就有5个,分别表示5种执行状态:
如下所示:
0 文件复制没有错误。
1 if errorlevel 2 echo。
2 用户按 CTRL+C 终止了 xcopy。
4 出现了初始化错误。没有足够的内存或磁盘空间,或命令行上输入了无效的驱动器名称或语法。
5 出现了磁盘写入错误。
要判断上面xcopy命令的5种退出情况,应写如下判断成才能正确执行:
if errorlevel 5 echo出现了磁盘写入错误
if errorlevel 4 echo出现了初始化错误
if errorlevel 2 echo用户按 CTRL+C 终止了 xcopy
if errorlevel 1 echo if errorlevel 2 echo
if errorlevel 0 echo文件复制没有错误。
@echo off Setlocal enabledelayedexpansion ::CODER BY dsw POWERD BY iBAT set /p var=随便输入一个命令 %var% ::等价于if %ERRORLEVEL% == 0 (echo !var!执行成功了) ELSE (echo !var!执行失败了!) if %ERRORLEVEL% == 0 ( echo !var!执行成功 ) else ( echo !var!执行失败 ) pause
这个是根据你输入的命令,自动判断是成功还是失败了!
第二种用法:IF [NOT] string1==string2 command
这个呢就是用来比较变量或者字符的值是不是相等的.
@echo off Setlocal enabledelayedexpansion ::CODER BY dsw POWERD BY iBAT set /p var1="请输入一个字符串:" set /p var2="请输入一个字符串:" if %var1% == %var2% ( echo var1 eque var2) else (echo var1 not eque var2) if NOT %var1% == %var2% ( echo var1 not eque var2) else (echo var1 eque var2) pause
上面这个例子可以判断你输入的值是不是相等,但是你如果输入相同的字符,但是如果其中一个后面打了一个空格,这个例子还是会认为相等,如何让有空格的输入不相等呢?我们在比较字符上加个双引号就可以了.
第三种用法:IF [NOT] EXIST filename command
这个就是判断某个文件或者文件夹是否存在的语法
@echo off Setlocal enabledelayedexpansion ::CODER BY dsw POWERD BY iBAT set file="C:\abc.bat" if exist %file% ( ::注意这里else后的空格 echo file is exists )else ( ::注意这里else要和if在同一行,并且else后要有空格 echo file is not exists )
判断的文件路径加引号是为了防止路径有空格,如果路径有空格加个双引号就不会出现判断出错了!
第四种用法:IF增强的用法
IF [/I] string1 compare-op string2 command #参数/I表示不区分大小写
IF CMDEXTVERSION number command
IF DEFINED variable command #判断变量是否存在,很有用
CMDEXTVERSION 条件的作用跟 ERRORLEVEL 的一样,除了它是在跟与命令扩展名有关联的内部版本号比较。第一个版本是 1。每次对命令扩展名有相当大的增强时,版本号会增加一个。命令扩展名被停用时,CMDEXTVERSION 条件不是真的。
如果已定义环境变量,DEFINED 条件的作用跟 EXISTS 的一样,下面两条命令效果一样。
IF DEFINED variable command
IF NOT "variable"=="" command
用“set variable=”命令使变量variable变成未定义,即空值,一句话,变量值为空,则为未定义;变量值不为空,则为已定义。
用语句IF DEFINED variable command判断变量是否存在时,请注意variable为不使用引导符号%的变量名,不能用写为%variable%,否则出错。
@echo off Setlocal enabledelayedexpansion ::CODER BY dsw POWERD BY iBAT set a=10 if DEFINED a (echo l hava define) else (echo l don't define) set a= if DEFINED a (echo l hava define) else (echo l don't define) pause 输出: l hava define l don't define
最后面还有一些用来判断数字的符号:
EQU - 等于
NEQ - 不等于
LSS - 小于
LEQ - 小于或等于
GTR - 大于
GEQ - 大于或等于