Bat脚本实现监控进程功能

Posted 笨小孩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bat脚本实现监控进程功能相关的知识,希望对你有一定的参考价值。

脚本间断监控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 dont define)
  set a=
  if DEFINED a (echo l hava define) else (echo l dont define)
pause

输出:
  l hava define
  l dont define

最后面还有一些用来判断数字的符号:
    EQU - 等于
    NEQ - 不等于
    LSS - 小于
    LEQ - 小于或等于
    GTR - 大于
    GEQ - 大于或等于

 

以上是关于Bat脚本实现监控进程功能的主要内容,如果未能解决你的问题,请参考以下文章

如何通过bat脚本与zabbix_sender实时监控应用进程是否正在运行

zabbix自定义脚本执行时间过长,怎样设置监控项呢?

代码片段:Shell脚本实现重复执行和多进程

Zabbix结合bat脚本实现多个应用程序状态监控

Zabbix结合bat脚本实现多个应用程序状态监控

根据进程名监控进程(邮件提醒)