脚本不间断监控notepad.exe进程是否执行,若停止,则自动重启该进程,程序如下:
@echo off set _task = notepad.exe
set _svr = c:\windows\notepad.exe
set _des = start.bat :checkService
for /f "tokens=5" %%n in ('qprocess.exe ^| find "%_task%" ') do (
if %%n==%_task% (goto checkMessage) else goto restartService
) :restartService
echo %time%
echo ********程序开始启动********
echo 程序重新启动于 %time% ,请检查系统日志 >> restart_service.txt
echo start %_svr% > %_des%
echo exit >> %_des%
start %_des%
REM set /p=.<nul 不换行在屏幕输出....
set /p=.<nul
for /L %%i in ( ) do set /p a=.<nul & ping.exe /n 127.0.0.1>nul
echo .
del %_des% /Q
echo ********程序启动完成********
goto checkService :checkMessage
echo %time% 程序运行正常,5秒后继续检查..
ping localhost -n
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 之后
@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
)
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% == (
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% == (
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% == (echo !var!执行成功了) ELSE (echo !var!执行失败了!)
if %ERRORLEVEL% == (
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=
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 - 大于或等于