批处理

来源:互联网 发布:中国拍卖网络拍卖平台 编辑:程序博客网 时间:2024/04/27 20:19

 

本教程由seco倾力撰写,本文以针对平常信息数据处理,为大家提供便捷操作为宗旨,现做以下讲解:

批处理基础
    
批处理定义:顾名思义,批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD。这些命令统称批处理命令。
1:
    @echo off
        echo "Hello World!"
    pause
 
将其保存以.bat.com后缀的文件即可以看到效果:"HelloWorld!" 请按任意键继续...
 
小技巧:按下ctrl+c可以强行中止正在运行的批处理

 


REM ::
    REM为注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显。
   
其次, :: 也可以起到rem 的注释作用, 而且更简洁有效; 但有两点需要注意:
   
第一, 任何以冒号:开头的字符行, 在批处理中都被视作标号, 而直接忽略其后的所有内容。
   
有效标号:冒号后紧跟一个以字母数字开头的字符串,goto语句可以识别。
   
无效标号:冒号后紧跟一个非字母数字的一个特殊符号,goto无法识别的标号,可以起到注释作用,所以 :: 常被用作注释符号,其实 :+ 也可起注释作用。
   
第二, rem 不同的是, ::后的字符行在执行时不会回显, 无论是否用echo on打开命令行回显状态, 因为命令解释器不认为他是一个有效的命令行, 就此点来看, rem 在某些场合下将比 :: 更为适用; 另外, rem 可以用于 config.sys 文件中。

行内注释格式:%注释内容%(不常用,慎用)

 

ECHO @
    @
字符放在命令前将关闭该命令回显,无论此时echo是否为打开状态。
    echo
命令的作用列举如下:
    1)打开回显或关闭回显功能

    格式:echo [{ on|off }]
   
如果想关闭“ECHO OFF”命令行自身的显示,则需要在该命令行前加上“@”
 
  2)显示当前ECHO设置状态
    格式:echo
   
3)输出提示信息
    格式:ECHO 信息内容
   
上述是ECHO命令常见的三种用法,也是大家熟悉和会用的,但作为DOS命令淘金者你还应该知道下面的技巧:
  
 4)关闭DOS命令提示符
   
DOS提示符状态下键入ECHO OFF,能够关闭DOS提示符的显示使屏幕只留下光标,直至键入ECHO ON,提示符才会重新出现。
  
 5)输出空行,即相当于输入一个回车
    格式:ECHO
   
值得注意的是命令行中的要紧跟在ECHO后面中间不能有空格,否则将被当作提示信息输出到屏幕。另外可以用,:;[//]+等任一符号替代。
   
命令ECHO.输出的回车,经DOS管道转向可以作为其它命令的输入,比如echo.|time即相当于在TIME命令执行后给出一个回车。所以执行时系统会在显示当前时间后,自动返回到DOS提示符状态
   6)答复命令中的提问
   
格式:ECHO 答复语|命令文件名
   
上述格式可以用于简化一些需要人机对话的命令(如:CHKDSKFFORMAT Drive:del *.*)的操作,它是通过DOS管道命令把ECHO命令输出的预置答复语作为人机对话命令的输入。下面的例子就相当于在调用的命令出现人机对话时输入“Y”回车:
    C:>ECHO Y|CHKDSK/F
    C:>ECHO Y|DEL A :*.*
    7)建立新文件或增加文件内容
   
格式:ECHO 文件内容>文件名
    ECHO
文件内容>>文件名
   
例如:
    C:>ECHO @ECHO OFF>AUTOEXEC.BAT
建立自动批处理文件
    C:>ECHO C://CPAV//BOOTSAFE>>AUTOEXEC.BAT
向自动批处理文件中追加内容
    C:>TYPE AUTOEXEC.BAT
显示该自动批处理文件
    @ECHO OFF
    C://CPAV//BOOTSAFE
   8)向打印机输出打印内容或打印控制码
    格式:ECHO 打印机控制码>RN
    ECHO
打印内容>RN
   
下面的例子是向M1724打印机输入打印控制码。<Alt156是按住Alt键在小键盘键入156,类似情况依此类推:
    C:>ECHO +156+42+116>RN
(输入下划线命令FSt
    C:>ECHO [email=+155@]+155@>RN[/email]
(输入初始化命令ESC@
    C:>ECHO.>RN
(换行)
   9)使喇叭鸣响
    C:>ECHO ^G
    “^G”
是在dos窗口中用CtrlGAlt007输入,输入多个^G可以产生多声鸣响。使用方法是直接将其加入批处理文件中或做成批处理文件调用。
   
这里的“^G”属于特殊符号的使用,请看本文后面的章节

执行ESC控制序列修改屏幕和键盘设置  

我们知道DOS的设备驱动程序ANSI.SYS提供了一套用来修改屏幕和键盘设置的ESC控制序列。如执行下述内容的批处理程序可以把功能键F12定义为DOS命令“DIRW”,并把屏幕颜色修改为白色字符蓝色背景。 

@ECHO”[0;134;”DIR/W”;13p  

@ECHO”[1;37;44m  

(注:批处理文件中字符的输入方法是在编辑状态下按Alt中小键盘上的27

 

 

  PAUSE
    PAUSE
,玩游戏的人都知道,暂停的意思
   
在这里就是停止系统命令的执行并显示下面的内容。
   
例:
    PAUSE
   
运行显示:
   
请按任意键继续. . .
   
要显示其他提示语,可以这样用:
    Echo
其他提示语 pause > nul

例子:

如果希望批处理程序提示用户更换驱动器中的磁盘,可创建如下批处理命令:

@echo off

    :begin

    copy a:*.*

    echo Please put a new disk into drive A

    pause

    goto begin

pause & exit 功用是不一样的。

exit是退出,不是可有可无,因为它可以用在循环体中。放在末尾当然无实际意义。
pause
是暂停,要求操作者互动,也就是程序运行到这一句的时候停下来,显示一条按下任意键继续……”的提示信息,等待操作者按任意键后继续执行下一步指令,后面的指令是什么,它就执行什么,不一定是退出。

 

 

errorlevel
   
程序返回码
    echo %errorlevel%
   
每个命令运行结束,可以用这个命令行格式查看返回码
   
用于判断刚才的命令是否执行成功
   
默认值为0,一般命令执行出错会设 errorlevel 1

扩充:

@echo off

dir z:

IF ERRORLEVEL 1 goto 1

IF ERRORLEVEL 0 goto 0

goto C

:0

echo 命令执行成功!

goto C

:1

echo 命令执行失败!

goto C

 

:C

echo 判断ERRORLEVEL返回号应该由高到低

PAUSE

 

 

或者

@echo off

dir c:

set "err=%ERRORLEVEL%"

IF "%err%"=="0" goto 0

IF "%err%"=="1" goto 1

goto C

:0

echo 命令执行成功!

goto C

:1

echo 命令执行失败!

goto C

 

:C

echo ERRORLEVEL返回号定义到一个变量由if判断

PAUSE

 

补充回答:返回值是多少在程序执行完后用echo%ERRORLEVEL%来查看该值, 每个命令基本返回值010成功1失败)特别是内部命令,不能一概的说是系统规定的,而是命令所指定的,第三方命令(外部命令)会提供多个甚至几十个返回值但最多 256±1 个返回值,各命令的返回值含义可能各不相同,其返回值含义及用法在此程序开发者原始自述文中有说明。

 

举例:

xcopy test.txt y:

if errorlevel 5 echo 出现了磁盘写入错误

if errorlevel 4 echo 出现了初始化错误

if errorlevel 2 echo 用户按CTRL+C终止

if errorlevel 1 echo 文件复制失败

if errorlevel 0 echo 文件复制成功

xxxx.exe 2>nul

if %errorlevel%==9009 xxxx.exe命令无效

 

title
   
设置cmd窗口的标题
    title
新标题#可以看到cmd窗口的标题栏变了

   在标题栏加上时间:

   title %time%

   在标题栏上显示当前的时间:

@echo off

:loop

title %time:~0,8%

ping -n 2127.1>nul

goto loop

time:~0,8è~0:时间的第一个位置。8:输出多少位的时间格式。

 

COLOR
   
设置默认的控制台前景和背景颜色。
    COLOR [attr]
    attr
指定控制台输出的颜色属性
   
颜色属性由两个十六进制数字指定 -- 第一个为背景,第二个则为
   
前景。每个数字可以为以下任何值之一:
    0 =
黑色 8 = 灰色
    1 =
蓝色 9 = 淡蓝色
    2 =
绿色 A = 淡绿色
    3 =
湖蓝色 B = 淡浅绿色
    4 =
红色 C = 淡红色
    5 =
紫色 D = 淡紫色
    6 = ** E =
**
    7 =
白色 F = 亮白色
   
如果没有给定任何参数,该命令会将颜色还原到 CMD.EXE 启动时
   
的颜色。这个值来自当前控制台窗口、/T 开关或
    DefaultColor
注册表值。
   
如果用相同的前景和背景颜色来执行 COLOR 命令,COLOR 命令
   
会将 ERRORLEVEL 设置为 1
   
例如: /"COLORfc/" 在亮白色上产生亮红色

批处理做的 COLOR TIME 彩色时间屏保

@echo off &setlocal EnableDelayedExpansion

mode con cols=100lines=40

title COLOR TIME

call :tnb

set font=█★●◆□◎◇¤⊙〓

:new

rem 主函数。

call :rdline

call :gt %time:~0,1%n

call :gt %time:~1,1%m

call :gt %time:~3,1%z

call :gt %time:~4,1%y

color 0%RANDOM:~-1%

setrdfont=!font:~%RANDOM:~-1%,1!

echo %nk%                  %date%

echo %nk% !%n%1:=%rdfont%! !%m%1:=%rdfont%!     !%z%1:=%rdfont%! !%y%1:=%rdfont%!

echo %nk% !%n%2:=%rdfont%! !%m%2:=%rdfont%!     !%z%2:=%rdfont%! !%y%2:=%rdfont%!

echo %nk% !%n%3:=%rdfont%! !%m%3:=%rdfont%! · !%z%3:=%rdfont%! !%y%3:=%rdfont%!

echo %nk% !%n%4:=%rdfont%! !%m%4:=%rdfont%!     !%z%4:=%rdfont%! !%y%4:=%rdfont%!

echo %nk% !%n%5:=%rdfont%! !%m%5:=%rdfont%! · !%z%5:=%rdfont%! !%y%5:=%rdfont%!

echo %nk%             www.cn-dos.net DOSCC WINBY.

ping 127.1 -n 3>NUL

cls

set nk=

goto :new

:rdline

rem 随机改变行数 左右位置。

set /A rdnb=%rdnb% +%RANDOM:~-1%

set /A rdnb=%rdnb% *2

set /A rdnb=%rdnb% +%RANDOM:~-1%

set /A rdnb=%rdnb% +%RANDOM:~-1%

for /L %%a in (%rdnb%-1 1) do echo.

set rdnb=0

set /A rdnb=%rdnb% +%RANDOM:~-1%

set /A rdnb=%rdnb% +%RANDOM:~-1%

set /A rdnb=%rdnb% *2

set /A rdnb=%rdnb% +%RANDOM:~-1%

for /L %%a in (1 1%rdnb%) do set nk=!nk!

set rdnb=0

goto :EOF

:gt

rem 得到时间 并替换成 数字模样。

if"%1"=="n" call :gt 0 n

if"%1"=="0" call set %2=a

if"%1"=="1" call set %2=b

if"%1"=="2" call set %2=c

if"%1"=="3" call set %2=d

if"%1"=="4" call set %2=e

if"%1"=="5" call set %2=f

if"%1"=="6" call set %2=g

if"%1"=="7" call set %2=h

if"%1"=="8" call set %2=i

if"%1"=="9" call set %2=j

goto :EOF

 

:tnb

rem 0-9 数字模样。

set a1=████

set a2=   

set a3=   

set a4=   

set a5=████

set b1= ██

set b2=   

set b3=   

set b4=   

set b5=   

set c1=████

set c2=     

set c3=████

set c4=     

set c5=████

set d1=████

set d2=     

set d3=████

set d4=     

set d5=████

set e1=   

set e2=   

set e3=████

set e4=     

set e5=     

set f1=████

set f2=     

set f3=████

set f4=     

set f5=████

set g1=████

set g2=     

set g3=████

set g4=   

set g5=████

set h1=████

set h2=   

set h3=     

set h4=     

set h5=     

set i1=████

set i2=   

set i3=████

set i4=   

set i5=████

set j1=████

set j2=   

set j3=████

set j4=     

set j5=████

goto :EOF

 

 

mode 配置系统设备
    配置系统设备。
   
串行口:    MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]
    [to=on|off] [xon=on|off] [odsr=on|off]
    [octs=on|off] [dtr=on|off|hs]
    [rts=on|off|hs|tg] [idsr=on|off]
   
设备状态: MODE [device][/STATUS]
   
打印重定向:   MODE LPTn[:]=COMm[:]
   
选定代码页:   MODE CON[:] CP SELECT=yyy
   
代码页状态:   MODE CON[:] CP [/STATUS]
   
显示模式:   MODE CON[:] [COLS=c] [LINES=n]
   
击键率:  MODE CON[:] [RATE=r DELAY=d]
   
例:
    mode con cols=113 lines=15 color 9f
   
此命令设置DOS窗口大小:15行,113

Global.exe一种病毒进程,现象是每隔30秒有个飘动的图片写的yourcomputer is being attacked,,还不停地发出噔噔的声音。

    附上自己在网上找到的几个批处理文件,以方便大家。

  版本一:

  @echo off

  title 未来病毒_专杀病毒批处理

  mode con: cols=100lines=50

  color a

  echo——————————————————————-

  echo 病毒资料

  echo 病毒资料U盘病毒

  echo 病症:创建Global.exe 进程! 木马病毒综合体 电脑速度明显下降

  echo 危险程度:高(不高才怪)

  echo 病毒:是

  echo 木马:是

  echo 恶意软件:否

  echo 建议:下载安装所有系统安全补丁

  echo BY: 未来病毒

  echo———————————————–

  set /p tmp=以上是该病毒的资料,按回车键开始清除该病毒

  taskkill /imGlobal.exe /f

  taskkill /imFonts.exe /f

  taskkill /imexplorer.exe /f

  delC:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/*.*

  delc:/windows/system32/dllcache/*.*

  del%System%/autorun.inf

  for /D %%d in(c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) do if exist %%d:/autorun.infattrib -s -h -r %%d:/autorun.inf

  for /D %%d in(c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) do if exist %%d:/autorun.infdel %%d:/autorun.inf /q

  for /D %%d in(c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) do if exist %%d:/autorun.infattrib -s -h -r %%d:/lcg.exe

  for /D %%d in(c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) do if exist %%d:/autorun.infdel %%d:/lcg.exe /q

  C:

  cd C:/windows/

  attrib -s -h -rc:/windows/system32/drivers/drivers.cab.exe

  delc:/windows/system32/drivers/drivers.cab.exe

  attrib -s -h -rC:/WINDOWS/system32/NMWizardA14.exe

  delC:/WINDOWS/system32/NMWizardA14.exe

  attrib -s -h -rC:/WINDOWS/pchealth/Global.exe

  delC:/WINDOWS/pchealth/Global.exe

  attrib -s -h -rC:/WINDOWS/pchealth/helpctr/binaries/HelpHost.com

  delC:/WINDOWS/pchealth/helpctr/binaries/HelpHost.com

  attrib -s -h -rC:/WINDOWS/system/KEYBOARD.exe

  delC:/WINDOWS/system/KEYBOARD.exe

  attrib -s -h -rC:/WINDOWS/Help/microsoft.hlp

  delC:/WINDOWS/Help/microsoft.hlp

  attrib -s -h -rC:/WINDOWS/system32/regedit.exe

  delC:/WINDOWS/system32/regedit.exe

  attrib -s -h -rC:/WINDOWS/system32/drivers/drivers.cab.exe

  delC:/WINDOWS/system32/drivers/drivers.cab.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/autorun.inf

  del C:/WINDOWS/system32/dllcache/autorun.inf

  attrib -s -h -rC:/WINDOWS/system32/dllcache/Default.exe

  delC:/WINDOWS/system32/dllcache/Default.exe

  attrib -s -h-rC:/WINDOWS/system32/dllcache/svchost.exe

  delC:/WINDOWS/system32/dllcache/svchost.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/Global.exe

  delC:/WINDOWS/system32/dllcache/Global.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/tskmgr.exe

  delC:/WINDOWS/system32/dllcache/tskmgr.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/explorer.exe

  delC:/WINDOWS/system32/dllcache/explorer.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/rndll32.exe

  delC:/WINDOWS/system32/dllcache/rndll32.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/system.exe

  delC:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/system.exe

  C:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/Global.exe

  delC:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/Global.exe

  attrib -s -h -rC:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/svchost.exe

  delC:/WINDOWS/system32/dllcache/Recycler.{645FF040-5081-101B-9F08-00AA002F954E}/svchost.exe

  attrib -s -h -rC:/WINDOWS/Fonts/tskmgr.exe

  delC:/WINDOWS/Fonts/tskmgr.exe

  attrib -s -h -rC:/WINDOWS/Fonts/Fonts.exe

  delC:/WINDOWS/Fonts/Fonts.exe

  attrib -s -h -rC:/WINDOWS/Media/rndll32.pif

  delC:/WINDOWS/Media/rndll32.pif

  attrib -s -h -rC:/WINDOWS/Cursors/Boom.vbs

  delC:/WINDOWS/Cursors/Boom.vbs

  del /f /s /q%systemdrive%/*.tmp

  del /f /s /q“%userprofile%/Local Settings/Temporary Internet Files/*.*”

  del /f /s /q“%userprofile%/Local Settings/Temp/*.*

  del /f /q%userprofile%/cookies/*.*

  start explorer.exe

  cls

  set /p tmp=清理病毒完毕!重新启动计算机后 重新运行 本批处理 以便于彻底 清理病毒,按回车键退出该程序

  echo BY:未来病毒

  :exit

Exit

 


GOTO :
    GOTO
会点编程的朋友就会知道这是跳转的意思。

GOTO命令只识别标号的前8个字符。
   
在批处理中允许以“:XXX”来构建一个标号,然后用GOTO XXX跳转到标号:XXX处,然后执行标号后的命令。
   
例:
    if {%1}=={} goto noparms
    if /"%2/"==/"/" goto noparms
   
标签的名字可以随便起,但是最好是有意义的字符串啦,前加个冒号用来表示这个字符串是标签,goto命令就是根据这个冒号(:)来寻找下一步跳到到那里。最好有一些说明这样你别人看起来才会理解你的意图啊。

例:
    @echo off
    :start
    set /a var+=1
    echo %var%
    if %var% leq 3 GOTO start
    pause
   
运行显示:
    1
    2
    3
    4

例子:goto :eofexit的区别:

@echo off
echo
你好!
call:hero
echo
再见!
pause
exit
:hero
echo
吃了吗?
goto :eof
echo
哈哈
------------------------------
执行结果是:
你好!
吃了吗?
再见!
请按任意键继续. . .
-------------------------
@echo off
echo
你好!
call:hero
echo
再见!
pause
exit
:hero
echo
吃了吗?
echo
哈哈
------------------------------
运行结果是:
你好!
吃了吗?
哈哈
再见!
请按任意键继续. . .
--------------------------------

从上面的运行结果可以看出好像是:程序遇到goto eof   马上返回 ,执行紧跟cal

后的那个语句了。如果没有goto eof 则程序要执行到本程序的结尾后才返回,执行紧跟call后的那个语句。

例子

for中用goto,for就不起作用了
同样,在if中用goto的话也是一样
SET a=4
IF %a% LSS 10 (
    ECHO 1
    IF %a% LSS 5 (
        GOTO ppp
        ECHO 2
:ppp
        ECHO 2.5
    )
) ELSE (
    ECHO 3
)
显示
1
2.5
3

 

find
   
在文件中搜索字符串。
    FIND [/V] [/C] [/N] [/OFF[LINE]] /"string/" [[drive:][path]filename[...]]
    /V
显示所有未包含指定字符串的行。
    /C
仅显示包含字符串的行数。
    /N
显示行号。
    /I
搜索字符串时忽略大小写。
    /OFF[LINE]
不要跳过具有脱机属性集的文件。
    /"string/"
指定要搜索的文字串,
    [drive:][path]filename
   
指定要搜索的文件。
   
如果没有指定路径,FIND 将搜索键入的或者由另一命令产生的文字。
    Find
常和type命令结合使用
    Type [drive:][path]filename | find /"string/"[&g
    t;tmpfile] #
挑选包含string的行
    Type [drive:][path]filename | find /v /"string/" #
剔除文件中包含string的行
    Type [drive:][path]filename | find /c #
显示文件行数
   
以上用法将去除find命令自带的提示语(文件名提示)

    例:
    @echo off
    echo 111 >test.txt
    echo 222 >>test.txt
    find /"111/" test.txt
    del test.txt
    pause
   
运行显示如下:
    ---------- TEST.TXT
    111
   
请按任意键继续. . .

例:
    @echo off
    echo 111 >test.txt
    echo 222 >>test.txt
    type test.txt|find /"111/"
    del test.txt
    pause
   
运行显示如下:
    111
   
请按任意键继续. . .

例如,下面的命令查找文件 Trade.txt 中存在的“Pacific Rim”字符串,并将结果保存Nwtrade.txt 文件中:

find"Pacific Rim" < trade.txt > nwtrade.txt

findfindstr 相比的优势:

 1、统计含指定字符串的总行数。find /c"abc" test.txt可以统计test.txt中含有字符串abc的总行数,而findstr则没有直接提供该功能,需要配合for语句才能实现;
  2find可以读取Unicode格式的文本,而findstr则不行;
  3find可以过滤某些特殊字符,而findstr则不行,比如,我们在使用fsutil fsinfodrives语句查询磁盘分区的时候,如果想让盘符分行显示而不是显示在同一行上的时候(这在用for语句提取盘符的时候很有用),find可以大显身手,而findstr只能干瞪眼了。

例子:

目的是将dir某个目录,如果存在某个文件夹就执行删除该文件夹的命令

for /f %%i in('dir /ad /b ^| find "要删除的文件夹"') do rd  /q/s %%i

 

 

start 命令
   
批处理中调用外部程序的命令(该外部程序在新窗口中运行,批处理程序继续往下执行,不理会外部程序的运行状况),如果直接运行外部程序则必须等外部程序完成后才继续执行剩下的指令
   
例:start explorer d://
   
调用图形界面打开D

语法:
START ["title"] [/MIN] [/MAX] [/WAIT]
参数:
["title"]
在窗口标题栏中显示的标题
[/MIN]
开始时窗口最小化
[/MAX]
开始时窗口最大化
[/WAIT]
启动应用程序并等候它结束

 

例子:启动记事本:

Start c:/windows/notepad.exe

Start c:/”windows”/notepad.exe

“c:/windows/notepad.exe”

C:/windows/notepad.exe

%windir%/notepad.exe

Path=%path%;notepad.exe& notepad.exe

 

 

assoc ftype
   
文件关联
    assoc
设置#39;文件扩展名&#39;关联,关联到&#39;文件类型&#39;
    ftype
设置#39;文件类型&#39;关联,关联到&#39;执行程序和参数&#39;
   
当你双击一个.txt文件时,windows并不是根据.txt直接判断用 notepad.exe 打开
   
而是先判断.txt属于 txtfile #39;文件类型&#39;
   
再调用 txtfile 关联的命令行 txtfile=%SystemRoot%//system32//NOTEPAD.EXE %1
   
可以在/"文件夹选项/"/"文件类型/"里修改这2种关联
    assoc #
显示所有#39;文件扩展名&#39;关联
    assoc .txt#
显示.txt代表的#39;文件类型&#39;,结果显示 .txt=txtfile
    assoc .doc#
显示.doc代表的#39;文件类型&#39;,结果显示 .doc=Word.Document.8
    assoc .exe#
显示.exe代表的#39;文件类型&#39;,结果显示 .exe=exefile
    ftype #
显示所有#39;文件类型&#39;关联
    ftype exefile #
显示exefile类型关联的命令行,结果显示 exefile=/"%1/" %*
    assoc .txt=Word.Document.8
   
设置.txtword类型的文档,可以看到.txt文件的图标都变了
    assoc .txt=txtfile
   
恢复.txt的正确关联

ftypeexefile=/"%1/" %*
   
恢复 exefile 的正确关联
   
如果该关联已经被破坏,可以运行 command.com ,再输入这条命令

 

pushd popd
   
切换当前目录
    @echo off
    c: cd// & md mp3 #
C:// 建立 mp3 文件夹
    md d://mp4 #
D:// 建立 mp4 文件夹
    cd /d d://mp4#
更改当前目录为 d://mp4
    pushd c://mp3#
保存当前目录,并切换当前目录为 c://mp3
    popd#
恢复当前目录为刚才保存的 d://mp4
   
一般用处不大,在当前目录名不确定时,会有点帮助。(dos编程中很有用)


CALL
    CALL
命令可以在批处理执行过程中调用另一个批处理,当另一个批处理执行完后,再继续执行原来的批处理
    CALL command
   
调用一条批处理命令,和直接执行命令效果一样,特殊情况下很有用,比如变量的多级嵌套,见教程后面。在批处理编程中,可以根据一定条件生成命令字符串,用call可以执行该字符串,见例子。
    CALL [drive:][path]filename [batch-parameters]
   
调用的其它批处理程序。filename 参数必须具有 .bat .cmd 扩展名。
    CALL :label arguments
   
调用本文件内命令段,相当于子程序。被调用的命令段以标签:label开头
   
以命令goto :eof结尾。
   
另外,批脚本文本参数参照(%0%1、等等)已如下改变:
   
批脚本里的 %* 指出所有的参数( %1 %2 %3 %4 %5 ...)
   
批参数(%n)的替代已被增强。您可以使用以下语法:(看不明白的直接运行后面的例子)
    %~1 -
删除引号(/"),扩充 %1
    %~f1-
%1 扩充到一个完全合格的路径名
    %~d1-
仅将 %1 扩充到一个驱动器号
    %~p1-
仅将 %1 扩充到一个路径
    %~n1-
仅将 %1 扩充到一个文件名
    %~x1-
仅将 %1 扩充到一个文件扩展名
    %~s1-
扩充的路径指含有短名
    %~a1-
%1 扩充到文件属性
    %~t1-
%1 扩充到文件的日期/时间
    %~z1-
%1 扩充到文件的大小
    %~$PATH : 1 -
查找列在 PATH 环境变量的目录,并将 %1
   
扩充到找到的第一个完全合格的名称。如果环境
   
变量名未被定义,或者没有找到文件,此组合键会
   
扩充到空字符串
   
可以组合修定符来取得多重结果:
    %~dp1 -
只将 %1 扩展到驱动器号和路径
    %~nx1 -
只将 %1 扩展到文件名和扩展名
    %~dp$PATH:1 -
在列在 PATH 环境变量中的目录里查找 %1
   
并扩展到找到的第一个文件的驱动器号和路径。
    %~ftza1 -
%1 扩展到类似 DIR 的输出行。
   
在上面的例子中,%1 PATH 可以被其他有效数值替换。
    %~
语法被一个有效参数号码终止。%~ 修定符不能跟 %*使用
   
注意:参数扩充时不理会参数所代表的文件是否真实存在,均以当前目录进行扩展
   
要理解上面的知识,下面的例子很关键。
   
例:
    @echo off
    Echo
产生一个临时文件 > tmp.txt
    Rem
下行先保存当前目录,再将c://windows设为当前目录
    pushd c://windows
    Call :sub tmp.txt
    Rem
下行恢复前次的当前目录
    Popd
    Call :sub tmp.txt
    pause
    Del tmp.txt
    exit
    :sub
    Echo
删除引号: %~1
    Echo
扩充到路径: %~f1
    Echo
扩充到一个驱动器号: %~d1
    Echo
扩充到一个路径: %~p1
    Echo
扩充到一个文件名: %~n1
    Echo
扩充到一个文件扩展名: %~x1
    Echo
扩充的路径指含有短名: %~s1
    Echo
扩充到文件属性: %~a1
    Echo
扩充到文件的日期/时间: %~t1
    Echo
扩充到文件的大小: %~z1
    Echo
扩展到驱动器号和路径:%~dp1
    Echo
扩展到文件名和扩展名:%~nx1
    Echo
扩展到类似 DIR 的输出行:%~ftza1
    Echo.
    Goto :eof
   
例:
    set aa=123456
    set cmdstr=echo %aa%
    call %cmdstr%
    pause
   
本例中如果不用call,而直接运行%cmdstr%,将显示结果%aa%,而不是123456

   由随机数来决定执行相应的程序段:

@echo off
set /a a=%random%%%10
echo %a%
pause
if %a% geq 5 (call :run2) else call :run1
goto :eof
:run1
echo
小于5
pause
goto :eof
:run2
echo
大于等于5
pause

 

 

shift
   
更改批处理文件中可替换参数的位置。
    SHIFT [/n]
   
如果命令扩展名被启用,SHIFT 命令支持/n 命令行开关;该命令行开关告诉
   
命令从第 n 个参数开始移位;n 介于零和八之间。例如:
    SHIFT /2
   
会将 %3 移位到 %2,将 %4 移位到 %3,等等;并且不影响 %0 %1

 

例子:一个强大的SHIFT5加密批处理

@echo off
title SHIFT5
加密批处理
set times=4
set mm=woyaoshenmele
set pass=
你的密码
:loop
set /A times=%times%-1
set /p input=
请输入密码:
if %times%==0 goto end
if not "%input%"=="%pass%" cls&goto loop
echo
密码正确,按任意键继续...&pause>nul
@goto start

:start
color A
cls
echo SHIFT5
加密批处理
echo greyair
echo.
echo ==============================
echo
请选择要进行的操作,然后按回车
echo ==============================
echo.
echo 1.
运行cmdshell
echo.
echo 2.
运行桌面程序
echo.
echo 3.
运行计算机管理
echo.
echo 4.
添加用户
echo.
echo 5.
删除用户
echo.
echo 6.
克隆用户
echo.
echo 7.
检查克隆用户
echo.
echo 8.
重启机器
echo.

:cho
set choice=
set /p choice=
请选择:
IF NOT "%choice%"=="" SET Choice=%Choice:~0,1%
if /i "%choice%"=="1" call:cmdshell
if /i "%choice%"=="2" call:explorer
if /i "%choice%"=="3" call:computer
if /i "%choice%"=="4" call:adduser
if /i "%choice%"=="5" call:deluser
if /i "%choice%"=="6" call:clone
if /i "%choice%"=="7" call:check
if /i "%choice%"=="8" call:reboot
echo
选择无效,请重新输入
echo.
goto cho

:cmdshell
echo
开始运行cmdshell
cacls.exe %windir%/system32/cmd.exe /e /t /g system:F
start cmd.exe /k cd/d %windir%/system32
echo
运行成功
pause >nul
GOTO :start

:explorer
echo
开始运行桌面程序
start Explorer.exe %windir%
echo
运行成功
pause >nul
GOTO :start

:computer
echo
开始运行计算机管理
start compmgmt.msc
echo
运行成功
pause >nul
GOTO :start

:ADDUSER
ECHO
开始添加用户
SET /P N=
请输入要添加的用户:
NET USER %N% /ADD
NET USER %N% h4ck3rsbr
NET USER %N% /ACTIVE:YES
NET LOCALGROUP ADMINISTRATORS %N% /ADD
ECHO
添加成功,帐号%N%,密码h4ck3rsbr
pause >nul
GOTO :start

:DELUSER
ECHO
开始删除用户
SET /P U=
请输入要删除的用户:
SET REGKEY=HKLM/SAM/SAM/Domains/Account/Users/
REG EXPORT %REGKEY%Names/%U% %U%.REG||EXIT/B
FOR /F "TOKENS=2 DELIMS=()" %%F IN ('FIND /I "@=HEX"%U%.REG') DO SET RID=%%F
REG DELETE %REGKEY%Names/%U% /F
REG DELETE %REGKEY%00000%RID% /F
NET USER %U% /ADD
NET USER %U% /DEL
REM
删除用户目录
IF EXIST %SYSTEMDRIVE%/DOCUME~1/%U%/NUL RD /S /Q"%SYSTEMDRIVE%/DOCUME~1/%U%"
DEL %U%.REG
echo
删除成功
pause >nul
GOTO :start

:CLONE
::
克隆的帐号必须存在,而且最好是系统内置帐号
SET REGKEY=HKLM/SAM/SAM/Domains/Account/Users/
SET /P AD=
请输入管理员用户名:
SET /P UN=
请输入要克隆的用户名:
SET /P PW=
请输入要克隆的密码:
REG EXPORT %REGKEY%Names/%AD% %AD%.REG
FOR /F "TOKENS=2 DELIMS=()" %%F IN ('FIND /I "@=HEX"%AD%.REG') DO SET CU=%%F
DEL %AD%.REG
::
修改密码
NET USER %UN% %PW%||EXIT/B
::
导出帐号的相对标志符
REG EXPORT %REGKEY%Names/%UN% %UN%.REG
FOR /F "TOKENS=2 DELIMS=()" %%F IN ('FIND /I "@=HEX"%UN%.REG') DO SET RID=%%F
::
取用户的F键数据
FOR /F "TOKENS=3" %%I IN ('REG QUERY %REGKEY%00000%RID% /V F') DO(SET F_KEY=%%I)
::
将修改后的数据导入
REG ADD %REGKEY%00000%RID% /F /V F /T REG_BINARY /D ^
%F_KEY:~0,96%%CU:~1%0%CU:~0,1%%F_KEY:~100,12%10%F_KEY:~114%
DEL %UN%.REG
pause >nul
GOTO :start

:CHECK
SET REGKEY=HKLM/SAM/SAM/Domains/Account/Users/
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO >"Account List"
FINDSTR /V / "Account List" /X 2>NUL
DEL "Account List"
ECHO.
ECHO RID(0x) Account
FOR /F "TOKENS=8 DELIMS=/" %%F IN ('REG QUERY %REGKEY%Names') DO (
REG EXPORT %REGKEY%Names/%%F %%F.REG>NUL
FOR /F "TOKENS=2 DELIMS=()" %%G IN ('FIND /I "@=HEX"%%F.REG') DO (
ECHO [%%G] [%%F]
NET USER %%F|FIND /I"*Administrators">NUL&&SET,=%%F/!,!&&SETADMINS=%%F%%G !ADMINS!||SET USERS=%%F%%G !USERS!
)
DEL %%F.REG
)
ECHO.
ECHO [%,:~0,-1%]>"Administrators Contains"
FINDSTR /V : "Administrators Contains" /X 2>NUL
DEL "Administrators Contains"
ECHO.
ECHO >"Check Result"
FINDSTR /V / "Check Result" /X 2>NUL
DEL "Check Result"
ECHO.
FOR %%I IN (%ADMINS%) DO (
FOR %%J IN (%USERS%) DO (
SET C1=%%I&&SET C1FRID=!C1:~-2!0!C1:~-3,1!
SET C2=%%J&&SET C2RID=!C2:~-3!
FOR /F "TOKENS=3" %%K IN ('REG QUERY %REGKEY%00000!C2RID! /V F') DO(SET C2.F=%%K)
IF /I "!C2.F:~96,4!"=="!C1FRID!" IF"!C2.F:~112,2!"=="10" ECHO [!C2:~0,-3!] ^<==^>[!C1:~0,-3!]
)
)
ECHO.
SET/P=Press [Enter] to exit...&&PAUSE>NUL
GOTO :start


:REBOOT
SET /P BOOT=
是否重启(Y:,N:):
IF NOT "%BOOT%"=="y" IF NOT"%BOOT%"=="Y" CLS&GOTO :START
SHUTDOWN -r -f -t 01
ECHO
系统正在重启...&pause>nul
GOTO :END


:END
DEL %0
EXIT

 

 

IF
    IF
条件判断语句,语法格式如下:
    IF [NOT] ERRORLEVEL number command
    IF [NOT] string1==string2 command
    IF [NOT] EXIST filename command
   
下面逐一介绍,更详细的分析请看后面章节。

    (1) IF [NOT] ERRORLEVEL number command
    IF ERRORLEVEL
这个句子必须放在某一个命令的后面,执行命令后由IF ERRORLEVEL 来判断命令的返回值。
    Number
的数字取值范围0~255,判断时值的排列顺序应该由大到小。返回的值大于等于指定的值时,条件成立
   
例:
    @echo off
    dir c:
    rem
退出代码为>=1就跳至标题1处执行,>=0就跳至标题0处执行
    IF ERRORLEVEL 1 goto 1
    IF ERRORLEVEL 0 goto 0
    Rem
上面的两行不可交换位置,否则失败了也显示成功。
    :0
    echo
命令执行成功!
    Rem
程序执行完毕跳至标题exit处退出
    goto exit
    :1
    echo
命令执行失败!
    Rem
程序执行完毕跳至标题exit处退出
    goto exit
    :exit
    pause
   
运行显示:命令执行成功!
    (2) IF [NOT] string1==string2 command
    string1
string2都为字符的数据,英文内字符的大小写将看作不同,这个条件中的等于号必须是两个(绝对相等的意思)
   
条件相等后即执行后面的command
   
检测当前变量的值做出判断,为了防止字符串中含有空格,可用以下格式
    if [NOT] {string1}=={string2} command
    if [NOT] [string1]==[string2] command
    if [NOT] /"string1/"==/"string2/"command
   
这种写法实际上将括号或引号当成字符串的一部分了,只要等号左右两边一致就行了,比如下面的写法就不行:
    if {string1}==[string2] command

(3) IF [NOT] EXISTfilename command
    EXIST filename
为文件或目录存在的意思
    echo off
    IF EXIST autoexec.bat echo
文件存在!
    IF not EXIST autoexec.bat echo
文件不存在!
   
这个批处理大家可以放在C盘和D盘分别执行,看看效果

执行批处理程序中的条件处理。 
IF [NOT] ERRORLEVEL number command 
IF [NOT] string1==string2 command 
IF [NOT] EXIST filename command 
  NOT               
指定只有条件为 false 的情况下, W indows XP  
                    
应该执行该命令。 
  ERRORLEVEL number 
如果最后运行的程序返回一个等于或大于 
                    
指定数字的退出编码,指定条件为 true  
  string1==string2  
如果指定的文字字符串匹配,指定条件为 true  
  EXIST filename    
如果指定的文件名存在,指定条件为 true  
  command           
如果符合条件,指定要执行的命令。如果指定的 
                     
条件为 FAL SE,命令后可跟一个执行 ELSE 
                      
关键字后的命令的 ELSE 命令。 
ELSE 
子句必须在 IF 之后出现在同一行上。例如
    IF EXIST filename ( 
        del filename 
    ) ELSE ( 
        echo filename missing 
    ) 


IF [NOT] ERRORLEVEL number command 
这个用法的基本做用是判断上一条命令执行结果的代码,以决定下一个步骤
一般上一条命令的执行结果代码只有两结果,"成功"表示  "失败"表示
举个例子
@echo off 
net user 
IF %ERRORLEVEL% == 0 echo net user 
执行成功了
pause 
这是个简单判断上条命令是否执行成功
细心的朋友可能会发现,这个用法和帮助里的用法不太一样,按照帮助里的写法"IF %ERRORLEVEL% == 0 
echo net user 
执行成功了!  "这一句代码应该写成:IF ERRORLEVEL 0 echo net user 执行成功了
那为什么我要写成这样呢?各位自己把代码改掉执行后,就会发现错误了!用这种语法,不管你的上面的命令
是否执行成功,他都会认为命令成功了,不知道是BUG 还是本人理解错误... 
补充:这不是bug,而是 if errorlevel 语句的特点:当使用 if errorlevel 0 …… 的句式时,它的含义是:
如果错误码的值大于或等于的时候,将执行某个操作;当使用 if %errorlevel%==0 …… 的句式时,它
的含义是:如果错误码的值等于的时候,将执行某操作。因为这两种句式含义的差别,如果使用前一种
句式的时候,错误码语句的排列顺序是从大到小排列 
%ERRORLEVEL% 
这是个系统变量,返回上条命令的执行结果代码! " 成功"表示  "失败"表示
然还有其他参数,用的时候基本就这两数字
一般上一条命令的执行结果代码只有两结果,"成功"表示  "失败"表示 
  
这只是一般的情况,实际上,errorlevel 返回值可以在0~255 之间,比如,xcopy 默认的errorlevel 
就有个,分别表示种执行状态: 
退出码 说明 
文件复制没有错误。 
1 if errorlevel 2 echo
 
用户按 CT RL+C 终止了 xcopy  
出现了初始化错误。没有足够的内存或磁盘空间,或命令行上输入了无效的驱动器名称或语法。 
出现了磁盘写入错误。 
要判断上面xcopy 命令的种退出情况,应写成: 
if errorlevel 5 echo 
出现了磁盘写入错误 
if errorlevel 4 echo 
出现了初始化错误 
if errorlevel 2 echo 
用户按 CTRL+C 终止了 x copy 
if errorlevel 1 echo if errorlevel 2 echo 
if errorlevel 0 echo 
文件复制没有错误。 
才能正确执行。 
补充完毕。 
再举几个例子给新手理解 
@echo off 
net usertest 
IF %ERRORLEVEL% == 1 echo net user 
执行失败了
pause 
这个是判断上一条命令是否执行失败的 
@echo off 
set /p var=
随便输入个命令
%var% 
if %ERRORLEVEL% == 0 goto yes 
goto no :yes 
echo !var! 
执行成功了 
pause 
exit 
:no 
echo 
基本上执行失败了.. 
pause 
这个是根据你输入的命令,自动判断是成功还是失败了
在来一个简化版的 
@echo off 
set /p var=
随便输入个命令
%var% 
if %ERRORLEVEL% == 0 (echo %var%
执行成功了) ELSE echo %var%执行失败了
pause 
else 
后面写上执行失败后的操作
当然我门还可以把if else 这样的语句分成几行写出来,使他看上去好看点... 
@echo off 
set /p var=
随便输入个命令
%var% 
if %ERRORLEVEL% == 0  ( 
   echo !var! 
执行成功了 
   ) ELSE ( 
   echo 
基本上执行失败了.. 
   ) 
pause 
这里介绍的两种简写对IF 的三种语法都可以套用,不单单是在IF [NOT] ERRORLEVEL number command 
这种法上才能用 


IF [NOT] string1==string2 command 
这个呢就是用来比较变量或者字符的值是不是相等的
例子 
@echo off 
set /p var=
请输入第一个比较字符
set /p var2=
请输入第二个比较字符
if %var% == %var2% (echo 
我们相等) ELSE echo 我们不相等 
pause 
上面这个例子可以判断你输入的值是不是相等,但是你如果输入相同的字符,但是如果其中一个后面打了一
个空格
这个例子还是会认为相等,如何让有空格的输入不相等呢?我们在比较字符上加个双引号就可以了
@echo off 
set /p var=
请输入第一个比较字符
set /p var2=
请输入第二个比较字符(多输入个空格试试): 
if "%var%" == "%var2%" (echo 
我们相等) ELSE echo 我们不相等 
pause  


IF [NOT] EXIST filename command 
这个就是判断某个文件或者文件夹是否存在的语法 
例子 
@echo off 
if exist "c:/test" (echo 
存在文件) ELSE echo 不存在文件 
pause 
判断的文件路径加引号是为了防止路径有空格,如果路径有空格加个双引号就不会出现判断出错了
这个语法没什么太多的用法,基本就这样了,就不多介绍了
另外我们看到每条IF 用法后都有个[NOT]语句,这啥意思?其他加上他的话,就表示先判断我们的条件不成立

没加他默认是先判断条件成立时,比如上面这个例子 
@echo off 
if not exist "c:/test" (echo 
存在文件) ELSE echo 不存在文件 
pause 
加个NOT,执行后有什么结果,如果你的盘下根本就没c:/test,他还是会显示"存在文件",这就表示了加了
NOT 
 
会先判断条件失败!懂了吧,上面例子改成这样就正确了
@echo off 
if not exist "c:/test" (echo 
不存在文件) ELSE echo 存在文件 
pause 
第四种用法:IF 增强的用法 
  IF [/I] string1 compare-op string2 command  #
参数/I 表示不区分大小写 
  IF CMDEXTVERSION number command 
  IF DEFINED variable command  #
判断变量是否存在,很有用 
CMDEXTVERSION 
条件的作用跟 ERRORLEVEL 的一样,除了它 
是在跟与命令扩展名有关联的内部版本号比较。第一个版本 
 1。每次对命令扩展名有相当大的增强时,版本号会增加一个。 
命令扩展名被停用时,CMDEXTVERSION 条件不是真的。 
如果已定义环境变量,DEFINED 条件的作用跟 EX ISTS 的一样 
IF DEFINED variable command 
IF NOT "variable"=="" command 
上面两条命令效果一样。 
“set variable=”命令使变量variable 变成未定义,即空值。 
一句话,变量值为空,则为未定义;变量值不为空,则为已定义。 
用语句IF DEFINED variable command 判断变量是否存在时,请注意variable 为不使用引导符号%的变量
名,不能用写为%variable%,否则出错。 
例: 
if defined aa (echo 
变量aa 存在) else (echo 变量aa 不存在
运行显示:变量aa 不存在 
例: 
set aa=123 
set aa= 
if defined aa (echo 
变量aa 存在) else (echo 变量aa 不存在
运行显示:变量aa 不存在 
例: 
@echo off 
if a == A (echo 
我们相等) ELSE echo 我们不相等 
pause 
执行后会显示:我们不相等 
例: 
@echo off 
if /i a == A (echo 
我们相等) ELSE echo 我们不相等 
pause 
加上/I 不区分大小写就相等了
最后面还有一些用来判断数字的符号 
    EQU - 
等于 
    NEQ - 
不等于 
    LSS - 
小于 
    LEQ - 
小于或等于 
    GTR - 
大于 
    GEQ - 
大于或等于 
我就举一个例子,大家都懂数学...不讲多了 
@echo off 
set /p var=
请输入一个数字
if %var% LEQ  4 (echo 
我小于等于4) ELSE echo 我不小于等于
pause 

 

setlocal 变量延迟
   
本条内容引用[英雄出品]的批处理教程:
   
要想进阶,变量延迟是必过的一关!所以这一部分希望你能认真看。
   
为了更好的说明问题,我们先引入一个例子。
   
1:
    @echo off
    set a=4
    set a=5 echo %a%
    pause
   
结果:4
   
解说:为什么是4而不是5呢?在echo之前明明已经把变量a的值改成5了?
   
让我们先了解一下批处理运行命令的机制:
   
批处理读取命令时是按行读取的(另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行),在处理之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。我们现在分析一下例1,批处理在运行到这句“set a=5 echo %a%”之前,先把这一句整句读取并做了预处理——对变量a赋了值,那么%a%当然就是4了!(没有为什么,批处理就是这样做的。)
   
而为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值,也就是说延迟了对变量的赋值。
   
那么如何开启变量延迟呢?变量延迟又需要注意什么呢?举个例子说明一下:
   
2:
    @echo off
    setlocal enabledelayedexpansion
    set a=4
    set a=5 echo !a!
    pause
   
结果:5
   
解说:启动了变量延迟,得到了正确答案。变量延迟的启动语句是“setlocalenabledelayedexpansion”,并且变量要用一对叹号“!!”括起来(注意要用英文的叹号),否则就没有变量延迟的效果。
   
分析一下例2,首先“setlocal enabledelayedexpansion”开启变量延迟,然后“set a=4”先给变量a赋值为
    4
“set a=5 echo !a!”这句是给变量a赋值为5并输出(由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该行变量赋值,而是在运行过程中给变量赋值,因此此时a的值就是5了)。
   
再举一个例子巩固一下。
   
3:
    @echo off
    setlocal enabledelayedexpansion
    for /l %%i in (1,1,5) do (
    set a=%%i
    echo !a!
    )
    pause
   
结果:
    1
    2
    3
    4
    5
   
解说:本例开启了变量延迟并用“!!”将变量扩起来,因此得到我们预期的结果。如果不用变量延迟会出现什
   
么结果呢?结果是这样的:
    ECHO
处于关闭状态。
    ECHO
处于关闭状态。
    ECHO
处于关闭状态。
    ECHO
处于关闭状态。
    ECHO
处于关闭状态。
   
即没有感知到for语句中的动态变化。
   
提示:在没有开启变量延迟的情况下,某条命令行中的变量改变,必须到下一条命令才能体现。这一点也可以加以利用,看例子。
   
例:交换两个变量的值,且不用中间变量
    @echo off
    ::
目的:交换两个变量的值,但是不使用临时变量
    ::Code by JM 2007-1-24 [email=CMD@XP]CMD@XP[/email]
    ::
出处:http://www.cn-dos.net/forum/viewthread.php?tid=27078
    set var1=abc
    set var2=123
    echo
交换前: var1=%var1%var2=%var2%
    set var1=%var2% set var2=%var1%
    echo
交换后: var1=%var1%var2=%var2%
    pause

ATTRIB显示或更改文件属性
    ATTRIB [+R|-R] [+A|-A] [+S|-S] [+H|-H] [[drive:] [path] filename][/S [/D]]
    +
设置属性。
    -
清除属性。
    R
只读文件属性。
    A
存档文件属性。
    S
系统文件属性。
    H
隐藏文件属性。
    [drive:][path][filename]
   
指定要处理的文件属性。
    /S
处理当前文件夹及其子文件夹中的匹配文件。
    /D
也处理文件夹。

    例:
    md autorun
    attrib +a +s +h autorun
   
上面的命令将建立文件夹autorun,然后将其设为存档、系统、隐藏属性


、常用特殊符号
    CR(0D) 命令行结束符
    Escape(1B) ANSI
转义字符引导符
    Space(20)
常用的参数界定符
    Tab(09) ; =
不常用的参数界定符
    + COPY
命令文件连接符
    * ?
文件通配符
    /
参数开关引导符
    :
批处理标签引导符

  首先, @ 不是一个命令而是DOS 批处理的一个特殊标记符仅用于屏蔽命令行回显下面是DOS命令行或批处理中可能会见到的一些特殊标记符
  CR(0D) 
命令行结束符 
  Escape(1B) ANSI
转义字符引导符 
  Space(20) 
常用的参数界定符 
  Tab(09) ; = 
不常用的参数界定符 
  + COPY
命令文件连接符 
  * ? 
文件通配符 
  "" 
字符串界定符 
  | 
命令管道符 
  < > >> 
文件重定向符 
  @ 
命令行回显屏蔽符 
  / 
参数开关引导符 
  : 
批处理标签引导符 
  % 
批处理变量引导符 

@命令行回显屏蔽符
    这个字符在批处理中的意思是关闭当前行的回显。我们从前几课知道
    ECHO OFF
可以关闭掉整个批处理命令的回显,但不能关掉ECHO OFF这个命令,现在我们在ECHO OFF这个命令前加个@,就可以达到所有命令均不回显的要求

%批处理变量引导符
   
这个百分号严格来说是算不上命令的,它只是批处理中的参数而已(多个%一起使用的情况除外,以后还将详细介绍)。
   
引用变量用%var%,调用程序外部参数用%1%9等等
    %0%1%2%3%4%5%6%7%8%9%*
为命令行传递给批处理的参数
    %0
批处理文件本身,包括完整的路径和扩展名
    %1
第一个参数
    %9
第九个参数
    %*
从第一个参数开始的所有参数
   
参数%0具有特殊的功能,可以调用批处理自身,以达到批处理本身循环的目的,也可以复制文件自身等等。
   
例:最简单的复制文件自身的方法
    copy %0 d://wind.bat
   
小技巧:添加行内注释
    %
注释内容%(可以用作行内注释,不能出现重定向符号和管道符号)
   
为什么这样呢?此时注释内容其实被当作变量,其值是空的,故只起注释作用,不过这种用法容易出现语法错误,一般不用。

 

 

>重定向符
   
输出重定向命令
   
这个字符的意思是传递并且覆盖,他所起的作用是将运行的结果传递到后面的范围(后边可以是文件,也可以是默认的系统控制台)
   
NT系列命令行中,重定向的作用范围由整个命令行转变为单个命令语句,受到了命令分隔符,&&,||和语句块的制约限制。
   
比如:
   
使用命令:echo hello >1.txt将建立文件1.txt,内容为”hello “(注意行尾有一空格)
   
使用命令:echo hello>1.txt将建立文件1.txt,内容为”hello“(注意行尾没有空格)

>>重定向符
   
输出重定向命令
   
这个符号的作用和>有点类似,但他们的区别是>>是传递并在文件的末尾追加,而>是覆盖
   
用法同上
   
同样拿1.txt做例子
   
使用命令:
    echo hello > 1.txt
    echo world >>1.txt
   
这时候1.txt 内容如下:
    hello
    world

 

 

<><&重定向符
   
这三个命令也是管道命令,但它们一般不常用,你只需要知道一下就ok了,当然如果想仔细研究的话,可以自己查一下资料。(本人已查过,网上也查不到相关资料)
    <
,输入重定向命令,从文件中读入命令输入,而不是从键盘中读入。
    @echo off
    echo 2005-05-01>temp.txt
    date <temp.txt
    del temp.txt
   
这样就可以不等待输入直接修改当前日期
    >
,将一个句柄的输出写入到另一个句柄的输入中。
    <
,刚好和>&相反,从一个句柄读取输入并将其写入到另一个句柄输出中。
   
常用句柄:012,未定义句柄:3—9
    1>nul
表示禁止输出正确的信息
    2>nul
表示禁止输出错误信息。
   
其中的12都是代表某个数据流输入输出的地址(NT CMD 称之为句柄,MSDOS称之为设备)。
   
句柄0:标准输入stdin,键盘输入
   
句柄1:标准输出stdout,输出到命令提示符窗口(console,代码为CON
   
句柄2:标准错误stderr,输出到命令提示符窗口(console,代码为CON
   
其中的stdin可被<重定向,stdout可被>>>重定向。
   
我们已经知道读取文本中的内容可以用for命令,但如果只需要读取第一行用for命令就有点麻烦。简单的办法如下:
    @echo off
    set /p str=<%0
    echo %str%
    pause
   
运行显示批处理文件自身的第一行:@echo off

 


|命令管道符
   
格式:第一条命令 | 第二条命令 [| 第三条命令...]
   
将第一条命令的结果作为第二条命令的参数来使用,记得在unix中这种方式很常见。
   
例如:
    dir c://|find /"txt/"
   
以上命令是:查找C//所有,并发现TXT字符串。
    FIND
的功能请用 FIND /? 自行查看
   
在不使format的自动格式化参数时,我是这样来自动格式化A盘的
    echo y|format a: /s /q /v:system
   
用过format的都知道,再格盘时要输入y来确认是否格盘,这个命令前加上echo y并用|字符来将echo y的结果传给format命令
   
从而达到自动输入y的目的
   
(这条命令有危害性,测试时请慎重)

 

^转义字符
    ^
是对特殊符号<,>,的前导字符,在命令中他将以上3个符号的特殊功能去掉,仅仅只把他们当成符号而不使用他们的特殊意义。
   
比如
    echo test ^>1.txt
   
结果则是:test > 1.txt
   
他没有追加在1.txt里,呵呵。只是显示了出来
   
另外,此转义字符还可以用作续行符号。
   
举个简单的例子:
    @echo off
    echo
英雄^
   
^
   
^
   
男人
    pause
   
不用多说,自己试一下就明白了。
   
为什么转义字符放在行尾可以起到续行符的作用呢?原因很简单,因为每行末尾还有一个看不见的符号,即回车符,转义字符位于行尾时就让回车符失效了,从而起到了续行的作用。

 

、组合命令
   
语法:第一条命令 第二条命令 [& 第三条命令...]
   
&&||为组合命令,顾名思义,就是可以把多个命令组合起来当一个命令来执行。这在批处理脚本里是允许的,而且用的非常广泛。因为批处理认行不认命令数目。
   
这个符号允许在一行中使用2个以上不同的命令,当第一个命令执行失败了,也不影响后边的命令执行。
   
这里两边的命令是顺序执行的,从前往后执行。
   
比如:
    dir z:// dir y:// & dir c://
   
以上命令会连续显示z,y,c盘的内容,不理会该盘是否存在

 


& 组合命令
   
语法:第一条命令 & 第二条命令 [&& 第三条命令...]
   
用这种方法可以同时执行多条命令,当碰到执行出错的命令后将不执行后面的命令,如果一直没有出错则一直执行完所有命令
   
这个命令和上边的类似,但区别是,第一个命令失败时,后边的命令也不会执行
    dir z:// & dir y:// && dir c://

 


||组合命令
   
语法:第一条命令 || 第二条命令 [|| 第三条命令...]
   
用这种方法可以同时执行多条命令,当一条命令失败后才执行第二条命令,当碰到执行正确的命令后将不执行后面的命令,如果没有出现正确的命令则一直执行完所有命令;

提示:组合命令和重定向命令一起使用必须注意优先级
   
管道命令的优先级高于重定向命令,重定向命令的优先级高于组合命令
   
问题:把C盘和D盘的文件和文件夹列出到a.txt文件中。看例:
    dir c:// & dir d:// > a.txt
   
这样执行后a.txt里只有D盘的信息!为什么?因为组合命令的优先级没有重定向命令的优先级高!所以这句在执行时将本行分成这两部分:dir c://dir d:// > a.txt,而并不是如你想的这两部分:dir c:// & dir d://> a.txt。要使用组合命令&&达到题目的要求,必须得这么写:
    dir c:// > a.txt & dir d:// >> a.txt
   
这样,依据优先级高低,DOS将把这句话分成以下两部分:dir c:// > a.txtdir d:// >> a.txt。例十八中的几句的差别比较特殊,值得好好研究体会一下。
   
当然这里还可以利用命令(自己想一下道理哦):
    dir c:// > a.txt dir d:// >> a.txt

 

 

/"/"字符串界定符
   
双引号允许在字符串中包含空格,进入一个特殊目录可以用如下方法
    cd /"program files/"
    cd progra~1
    cd pro*
   
以上三种方法都可以进入program files这个目录

 


, 逗号
   
逗号相当于空格,在某些情况下“,”可以用来当做空格使
   
比如
    dir,c://

 


; 分号
分号,当命令相同时,可以将不同目标用;来隔离,但执行效果不变,如执行过程中发生错误,则只返回错误报告,但程序仍会执行。(有人说不会继续执行,其实测试一下就知道了)
   
比如:
    dir c://;d://;e://;z://
   
以上命令相当于
    dir c://
    dir d://
    dir e://
    dir f://
   
如果其中z盘不存在,运行显示:系统找不到指定的路径。然后终止命令的执行。
   
例:dir c://;d://;e://1.txt
   
以上命令相当于
    dir c://
    dir d://
    dir e://1.txt
   
其中文件e://1.txt不存在,但e盘存在,有错误提示,但命令仍会执行。

为什么?如果目标路径不存在,则终止执行;如果路径存在,仅文件不存在,则继续执行。

 

 

()括号
   
小括号在批处理编程中有特殊的作用,左右括号必须成对使用,括号中可以包括多行命令,这些命令将被看成一个整体,视为一条命令行。
   
括号在for语句和if语句中常见,用来嵌套使用循环或条件语句,其实括号()也可以单独使用,请看例子。
   
例:
   
命令:echo 1 echo 2 &echo 3
   
可以写成:
    (
    echo 1
    echo 2
    echo 3
    )
   
上面两种写法效果一样,这两种写法都被视为是一条命令行。
   
注意:这种多条命令被视为一条命令行时,如果其中有变量,就涉及到变量延迟的问题。


!感叹号
   
没啥说的,在变量延迟问题中,用来表示变量,即%var%应该表示为!var!,请看前面的setlocal命令介绍。