windows批处理-cmd入门
shell简介
分类
第一个bat脚本
echo Hello world
echo用法
打印
创建一个文件
@echo off 关闭回显
命令
命令的基本格式
命令 子命令 参数 操作
ping 127.0.0.1 -n 3 > nul
帮助
/help
/?
长选项 短选项
命令不区分大小写
无缩进
在窗口里调用的命令分为两类,一类是原生的命令,还有一类是各种支持命令行的程序,两者使用的时候看着差不多。
1.内部命令(原生cmd)
首先在cmd命令输入help,看到如下图的结果,这里是原生的cmd
2.外部命令
其实那是window系统内嵌的程序(支持命令行)
外部执行程序的拓展:c/windows/system32/ping.exe
参数传递
bat脚本文件接受参数使用 %num
@echo off
echo %1
pause
注释
1.Rem 注释说明
2.::
@echo off
:: 这是一个注释
rem 这是一个注释
echo 注释
pause
返回值
errorlevel
上一条命令的执行结果
0:正常退出
1:异常退出
exit
退出窗口
EXIT [/B] [exitCode]
/b 退出当前脚本
exitCode 退出代码,可以被errorlevel获取
pause
暂停窗口. (提醒按键退出)
choice
命令可以让用户输入一个字符,从而运行不同的命令
@echo off
echo list
choice /c abcde /m "please input:" /d e /t 5
if %errorlevel% == 1 echo you choiced a
if %errorlevel% == 2 echo you choiced b
if %errorlevel% == 3 echo you choiced c
if %errorlevel% == 4 echo you choiced d
if %errorlevel% == 5 echo you choiced e
pause
相对路径,绝对路径和工作目录
cd 改变目录
打印当前目录
pushd 命令
改变当前目录到指定目录,并保存当前的目录在堆栈顶端
@echo off
echo %cd%
pushd %~dp0
echo %cd%
pause
popd 命令
改变当前目录,跳转到堆栈顶端保存的目录,并将堆栈顶端的目录删除
@echo off
echo %cd%
pushd %~dp0
echo %cd%
popd
echo %cd%
pause
start call cmd
cmd
创建一个cmd新实例,相当于cmd.exe
常和 /c 配合使用
cmd /c test.bat
call
语法: call [ [Drive:] [Path] FileName [BatchParameters]] [:label [arguments]]
参数: [Drive:][Path] FileName 指定要调用的批处理程序的位置和名称。Filename 参数必须是.bat 或 .cmd 扩展名的类型文件。
BatchParameters 指定批处理程序所需的命令行信息(即参数项)。
调用另一个批处理程序,并且不终止父批处理程序(如果不用call而直接调用别的批处理文件,那么执行完那个批处理文件后将无法返回当前文件并执行当前文件的后续命令)。
call 命令接受用作跳转目标的标签。如果在脚本或批处理文件外使用call,它将不会在命令行起作用。
@echo off
call :label
echo 1
echo 2
:label
echo 3
echo 4
可以很清晰的看到,call调用类似于函数调用的执行逻辑:call2相当于执行主函数,在其执行过程中,需要调用到call1函数,当call1执行结束后,call2主函数再继续执行本身的命令,直至整个过程结束。
start
启动一个单独的窗口以运行指定的程序或命令
/b 不创建新窗口运行
打开盘符 文件 程序 网址
start www.baidu.com
start test.bat
start cmd.exe
总结结论:
call的时候,他们拥有同一个壳cmd.exe,在同一个进程当中,所以他们的变量是互通的。
start的时候,他们拥有两个壳cmd.exe,但child.bat可以看成是main.bat的子进程,子进程可以读取父进程中的变量(即a的值)。
对于start,概括两句话:“不同进程不能传值”,“相同进程单向传值,老子传儿子,非儿子传老子”。
对于call,“同一进程,变量互通”。
start与call命令的区别:
一是调用范围不同:call主要用来进行批处理的内部调用,如call :pend 和一些dos命令的调用如call set test=2,但也可以调用其他可执行文件,而start则不能进行内部调用,但其可以执行基本上所有的外部程序,还可以执行shell,如打开文件夹start "" "%WINDIR%",安装网络打印机start "" "\\IP\Printer"等等。
二是调用方式不同:call是严格意义上而言的调用,在call另一个批处理时是在同一窗体进程里执行,而start则是执行,所以在执行另外一个批处理时是在不同的窗体进程里进行,也就是说在新开启的进程里执行,虽然start可以加入b参数,但其结果却完全不同。如我们使用call set test=2 和 start /b set test=2 看似执行的结果相同,但是我们发现后者有两个进程,而且在窗体里要执行两次exit才能退出,所以当我们使用start来执行一个批处理后最好在被调用的批处理中也加一个exit,否则无法退出被调用的批处理的dos窗体,但是使用call调用时如果在被调用的批处理中存在exit则会直接结束原始和被调用的批处理程序,这是一个非常严重的问题。建议在被调用的批处理中使用goto :eof来取代exit。
三是调用结果不同:call调用不仅可以把参数或变量传给被调用的批处理,而且被调用的批处理也可以设置参数或变量以便回传,而start只能把参数或变量传给被调用的批处理,却不能回传参数或变量,这一点实际上是第二点的延伸。另外,我们还必须注意一点:使用call调用其他批处理时,在被调用的批处理中若我们使用goto命令的时候,建议要使用与原批处理中不同的标签名来跳转,否则可能会跳转到原批处理中而不能保证完整的执行被调用批处理中的所有语句。
变量
set打印所有的环境变量
%PATH%。系统环境变量
set PATH=%PATH%;d:\workspace
变量设置 set
set a=1
变量不能有=号,如果有特殊字符,需要转义或者" "
set var=a^=b
set var="a=b"
set 变量名为空等于删除变量名
/p 等待用户输入
/a 可以表达式计算
变量引用
set a=1
echo %a%
setlocal与变量延迟
setlocal
@echo off
set PATH
pause
setlocal
set PATH=d:/workspace
set PATH
pause
endlocal
set PATH
pause
变量延迟
0) 在没有开启变量延迟的情况下,某条命令行中的变量改变,必须到下一条命令才能体现。
另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行。
example:
set a=4
set a=5 & echo %a%
结果:4
也可以对这种机制加以利用,如下的变量交换
example:
set var1=abc
set var2=123
echo 交换前: var1=%var1% var2=%var2%
set var1=%var2%& set var2=%var1%
echo 交换后: var1=%var1% var2=%var2%
1) 启动批处理文件中环境变量的本地化。本地化将持续到出现匹配的 endlocal 命令或者到达批处理文件结尾为止。
语法: setlocal {enableextension | disableextensions} {enabledelayedexpansion | disabledelayedexpansion}
enableextension: 启用命令扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
disableextensions: 禁用命令扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
enabledelayedexpansion: 启用延迟的环境变量扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
disabledelayedexpansion: 禁用延迟的环境变量扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
2) 为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值,也就是说“延迟”了对变量的赋值。
examle:
setlocal enabledelayedexpansion
set a=4
set a=5 & echo !a!
结果: 5
变量延迟的启动语句是“setlocal enabledelayedexpansion”,并且变量要用一对叹号“!!”括起来
由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该行变量赋值,而是在运行过程中给变量赋值,因此此时a的值就是5了
另外,启动变量延迟,“%”的变量还是不变
example2:
setlocal enabledelayedexpansion
for /l %%i in (1,1,5) do (
set a=%%i
echo !a!
)
结果,打印从1到5;如果不变量延迟,一个变量也没有打印
运算符
算术运算符
set /a 4+5
set /a var = 1+2
echo %var%
重定向运算符
>
echo hello world > test.txt
>>
echo a test > test.txt
<
set /a var=<test.txt
逻辑运算符
|
管道运算符:左边的执行结果作为参数传给右边
dir | find ’.txt’
netstat -an | find “ESTABLISHED”
|| 非
& 或
&& 与
eq ==
等于
ne !=
不等于
in 子集
转义字符
^
条件判断语句
if
If else
If else if else
@echo off
if %1 == a (
echo a
) else if %1 == b (
echo b
) else (
echo other
)
pause
else不允许直接是行首。同时要注意判断条件附近空格的使用
循环语句
格式:FOR [参数] %%变量名 IN (相关文件或命令) DO 执行的命令
作用:对一个或一组文件,字符串或命令结果中的每一个对象执行特定命令,达到我们想要的结果。
注意:在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable,而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I.
关于:for命令可以带参数或不带参数,带参数时支持以下参数:/d /l /r /f
无参数
FOR %variable IN (set) DO command [command-parameters]
%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件。可以使用通配符。
command 指定对每个文件执行的命令。
command-parameters
为特定命令指定参数或命令行开关。
--显示当前目录下与t*.*相匹配的文件(只显示文件名,不显示路径)
for %%i in (t*.*) do echo %%i
--显示d:\mydocuments\目录下与*.doc相匹配的文件
for %%i in (d:\mydocuments\*.doc) do @echo %%i
参数 /d (参数只能显示当前目录下的目录名字)
格式:FOR /D %variable IN (set) DO command [command-parameters]
这个参数主要用于目录搜索,不会搜索文件,/D 参数只能显示当前目录下的目录名字。(特别说明:只会搜索指定目录下的目录,不会搜索再下一级的目录。)
--显示c盘根目录下的所有目录
for /d %%i in (c:\*) do echo %%i
--显示当前目录下名字只有1-3个字母的目录
for /d %%i in (???) do echo %%i
参数 /R (搜索指定路径及所有子目录中与set相符合的所有文件)
格式:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
此命令会搜索指定路径及所有子目录中与set相符合的所有文件,注意是指定路径及所有子目录。
--枚举了c盘所有目录
for /r c:\ %%i in (boot.ini) do echo %%i
--枚举d\backup目录
for /r d:\backup %%i in (1) do echo %%i
--很好的搜索命令,列举boot.ini存在的目录
for /r c:\ %%i in (boot.ini) do if exist %%i echo %%i
参数 /L (该集表示以增量形式从开始到结束的一个数字序列。可以使用负的 Step)
格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]
该集表示以增量形式从开始到结束的一个数字序列。可以使用负的 Step
--输出100,80,60,40,20
for /l %%i in (100,-20,1) do @echo %%i
--打开5个CMD窗口
for /l %%i in (1,1,5) do start cmd
--建立从1~5共5个文件夹
for /l %%i in (1,1,5) do md %%i
参数 /F
格式 FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
假设a.txt某一行的内容是 111,222.333 444/555
for /f "skip=1 tokens=1,2* delims= " %%a in (a.txt) do echo %%a %%b %%c
skip=
for循环文本内容是以行为单位,从上至下进行的,skip=1意识就是跳过文本的第一行,即不循环第一行
那么skip=2 自然就是跳过前两行了,依次类推.........
delims=
delims=后面的字符是将文本每一行的内容以delims=后面的字符分割成若干列.
for /f "tokens=1-5 delims=,./ " %%a in (a.txt) do echo %%a %%b %%c %%d %%e
显示结果是 111 222 333 444 555
tokens=
tokens=1-5
1-5很好理解就1至5,前面我们用delims=后面的字符为分割符,将文本内容分成了多列,那么你需要的是哪些列呢?如上例:
通过dilims=,./ 将文本分成了111 222 333 444 555 五列.
注意代码中前面有个%%a 这里的%%a就是代表第一列,第二列就是%%b,第三列就是%%c 依此类推.....
那么我们如果把echo %%a %%b %%c %%d %%e 改为 echo %%e %%d %%c %%b %%a 会如何呢?
当然.会显示 555 444 333 222 111
如果是:echo %%b %%d 又会显示222 444
若是第一个%%a把它改为%%i也是一样,那么第二列就是%%j...%%k...依此类推....
明白了?就是按英文字母的顺序依此类推的.
如果用tokens=1,2* 有什么区别呢?
其实差不多-号代表从几至几而逗号代表单一的,如 tokens=1,5就是代表第一列和第五列,而不是1至5列.
*号代表剩下的所有的列.如:tokens=1,2*代表%%a为第一列,%%b为第二列,%%c代表后面所有的列.
for /f 不但可以循环文本内容还可以循环字符窜,如:
for /f "tokens=1-3 delims=,./ " %%a in ("111,222.333 444/555") do echo %%a %%b %%c
只要将()里的字符串用引号扩起来,for就会把它当字符串来循环,而不是文本.
for /f "tokens=1,3* delims=,./ " %%a in ("111,222.333 444/555") do echo %%a %%b %%c
按分隔符将字符串分段后,取第1、3、4-5三段分别作为%%a %%b %%c
for /f "tokens=1,3* delims=,./ " %a in ("111,222.333 444/555") do echo %a %b %c %d %e
结果显示111 333 444/555 %d %e
六.函数与goto
goto是个跳转命令,紧跟其之后的是标签名;冒号是一个标签标志,紧跟其之后的是标签名,两者合称标签。当程序运行到goto时,将自动跳转到冒号定义的部分去执行
goto part1
:part1
使用goto语句注意事项:
1. 一一对应。goto语句与标签要相互对应。不允许只有goto语句而没有相应的标签段,否则,程序将找不到相应的标签段而直接退出;只有标签段而没有goto语句是允许的,但不能实现流程跳转功能,从代码精简的角度来看,有标签段而没有goto语句,则此标签是多余的,大可精剪。
2. 多个标签。若有多个标签段,则需要注意标签段之间是否需要添加恰当的退出语句来终止程序继续向下执行。
3. 标签名只可以使用常量,而不能使用变量;
@echo off
set /p input=请输入字母A或B:
if "%input%"=="A" goto A
if "%input%"=="B" goto B
pause
exit
:A
echo 您输入的字母是A
pause
exit
:B
echo 您输入的字母是B
pause
exit
字符串操作
五、字符串处理
1) 分割字符串,以查看时间为例
%源字符串:~起始值,截取长度% (起始值从0开始;截取长度是可选的,如果省略逗号和截取长度,将会从起始值截取到结尾;
截取长度如果是负数,表示截取到倒数第几个。)
"%time%" 显示如:"11:04:23.03" (完整的时间"hh:mm:ss.tt")
"%time:~0,5%" 显示"hh:mm"(即"11:04"),其中0表示从右向左移位操作的个数,5表示从左向右移位操作的个数
"%time:~0,8%" 显示标准时间格式"hh:mm:ss"(即"11:04:23",前8个字符串)
"%time:~3,-3%"显示"mm:ss"(即从第4个开始,截去最后3个的字符串)
"%time:~3%" 显示"04:23.03"(即去掉前4个字符串)
"%time:~-3%" 显示".tt"(即最后3个字符串)
上面的字串分割格式,也可以用于其它地方,如目录路径:"%cd:~0,10%"
2) 替换字符串
set a="abcd1234"
echo %a% 显示:"abcd1234"
set a=%a:1=kk% 替换“1”为“kk”
echo %a% 显示:"abcdkk234"
3) 字符串合并
由于没有直接的字符串合并函数,只能用笨方法了。
set str1=%str1%%str2% (合并 str1 和 str2)
4) 计算字符串长度
没有现成的函数。如下程序利用 goto形成循环,不断将字符串截短1,并记录截短的次数,到字符串变成空时的次数即长度。
set testStr=This is a test string
:: 将 testStr 复制到str,str 是个临时字符串
set str=%testStr%
:: 标签,用于goto跳转
:next1
:: 判断str是不是空,如果不是则执行下边的语句
if not "%str%"=="" (
:: 算术运算,使num的值自增1,相当于num++或者++num语句
set /a num+=1
:: 截取字符串,每次截短1
set "str=%str:~1%"
:: 跳转到next1标签: 这里利用goto和标签,构成循环结构
goto next1
)
:: 当以上循环结构执行完毕时,会执行下边的语句
echo testStr=%testStr%
echo testStr的长度为:%num%
5) 截取字符串时,需要传递参数
直接 echo %args:~%num%,-5% 没办法想要的字符串,需要如下两步
setlocal enabledelayedexpansion
echo !args:~%num%,-5!
文件操作
dir 罗列目录
tree 文件树形结构
mkdir 创建文件夹
rmdir 删除文件夹
cd 进入文件夹
ren 文件夹改名
copy 复制
xcopy 复制
del 删除
move 移动
type 查看
more 逐行查看
sort 排序(不会修改原文件)
find 查找
进程
tasklist /s ip /u user /p password. 查看远程计算机进程列表
taskkill /im /f qq.exe
taskkill /pid 1234 /f
taskkill /fi ‘’PID eq 1234’’
远程桌面连接
mstsc /?
mstsc /v 10.66.192.136 /f /admin
创建定时任务
schtasks
SCHTASKS /Create /SC DAILY /TN gaming /TR c:\freecell /ST 12:00 /ET 14:00 /K
创建计划任务 "gaming",每天从 12:00 点开始到
14:00 点自动结束,运行 freecell.exe。
- 点赞
- 收藏
- 关注作者
评论(0)