1.前言
前面的几个章节我们简单学习了一下如何使用Linux系统,以及如何用VS来开发Linux程序。
一般来说,对于Linux的基础使用也就这样了:基本命令、开发程序。
想要更加深入的学习Linux,就还得学习各种常用软件的使用方法,以及更多命令。
而本章介绍的脚本,无论是在Windos
系统,还是Linux系统
上,都相当重要。
没错,C/C++程序员学的东西就是非常杂,基本什么都得会点。
一般在Linxu系统上使用脚本频率更高。
当然,各个系统之间的脚本编写方法是不同的,除非你使用一个中间层,比如python
语言,来抹平不同平台脚本的差异性,否则就得分别学习不同平台脚本的编写方式。
虽说是要学不同平台的脚本编写,看似有点多,但事实上脚本之间都有互通性,只是脚本的语法略有差异。
所以本章就来分别详细介绍这两种平台的脚本编写方式。
2.什么是脚本?
为了更加清晰地理解什么是脚本,最直观的方法就是看一看别人写的专业脚本到底长啥样。
大家应该都是装了VS的,所以我们就可以来到VS的一个用于搭建构造环境的脚本:
D:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Auxiliary\Build
根据大家安装的版本,位置,上面这个目录可能略有不同,可以自己调整,然后就可以看到下方的几个脚本文件:
没错,在Windows系统中以.bat
后缀结尾的文件,就是一个脚本文件(在Windows系统中,称其为批处理),双击它们,就可以像双击一个exe
程序一样,可以直接运行。
这里我们来看一看这个占用内存最大的脚本文件vcvarsall.bat:
不要直接点它,那是直接运行了,右键它,然后点击编辑:
然后我们就可以看到上面这些看起来很奇怪的字符串。
通过这里我们可以得出什么结论吗?
这说明脚本文件是不依赖于任何编译器的,我们可以直接在记事本里面写脚本,只要将其保存为.bat
后缀,就能直接点击运行!
是不是突然就理解那些用记事本编程的人了?看起来特别厉害的样子,也许就是一个脚本小子。
当然也不是贬低的意思,毕竟我们写出来的软件就是用来用的,能把软件用好也是一个技能。
这并不困难(至少与学习C/C++相比而言),所以我这里只使用了一章的篇幅来大致介绍两个平台的脚本开发流程
这里只介绍基础知识,想要更加深入的学习,就还得自行学习各种命令的高阶用法。
3.Windows脚本
首先我们直接来看Windows脚本的编写流程,毕竟绝大部分人应该都习惯于使用Windows。
注意:在脚本语言中,习惯于一行写一句命令,且命令前无空格。
技巧:windows命令的参数是通过/
传递的,如果不清楚一个命令如何用,就可以传入/?
,以获取命令的详细解释。
3.1 如何写脚本
那么我们应该如何写脚本呢?很简单,如前面所说,记事本即可
新建一个记事本,任意命名,但后缀需要更改为.bat
:
然后用记事本打开并编辑它。
如果你有其它编辑软件,甚至用VS打开它进行编辑,都是可以的。
然后输入一个pause
,即暂停的意思:
保存后,双击这个文件:
看到没,这就相当于我们自己进入控制台,然后输入pause
命令是一样的效果,而所谓脚本,就是将这些大量的命令放在一起,统一执行,以实现某些功能。
pause
这个命令的作用就是暂停,因为脚本文件执行完成后,就直接退出了,如果没有暂停按钮,你可能就啥也没看到,脚本就已经执行完了。
当你按下任意键,就会继续执行pause
命令之后的命令,如果后面没有命令了,就退出脚本文件
3.2 关闭回显
上面我们使用了一下pause
命令,但执行后,它会显示路径,以及执行的这个命令名称。
但有时候,我们就不喜欢它显示出来,怎么办呢?
关闭回显有两种方法:
- 关闭单个命令的回显
如果只想要关闭一条命令的回显,只需要在命令的最前面添加@
符号即可:
@pause
执行后:
没有回显是不是就好看多了!
- 关闭所有回显
上面那种方法只适用于关闭个别命令,想要关闭所有命令,就得在所有命令前面都添加@
,那未免就有点太麻烦了.
所以就有了直接一次性关闭所有命令回显的方法:
@echo off
pause
echo
这个命令就是用来显示字符串的,其后带上参数off
,就可以关闭当前脚本所有命令的自动回显。
然后再在这个命令前面添加@
,表示将这个echo off
命令本身的回显也关闭掉,这样就实现了整个脚本文件都处于无回显的状态了。
因为这里只有一个命令,所以看起来效果与前面相同,你可以在后面多添加几条命令,就会发现所有命令都没有回显,只会显示命令的执行结果。
3.3 注释
脚本语言同样也是有注释的,毕竟谁能在几个月乃至几年后还能记住当初自己写的是个什么玩意呢?
批处理脚本(windows平台下脚本的一般叫法)的注释方式有两种:
- 第一种是:
REM
后跟注释(小写也可,其后要与注释有空格) - 第二种是:
:
后跟注释
比如上面的:
这两个其后跟着的就是命令注释。
注意rem
本身也是一个命令,所以也会有回显,因此VS在前面添加了@
,以关闭回显,而:
不是命令,没有回显,不需要关闭回显。
3.4 输出(echo)
作为脚本语言,输出肯定是不可或缺的。
而批处理文件中的输出命令就是echo
,前面我们也提到过,它还可以关闭回显。
其使用方法很简单,就是将你想要显示出来的内容跟在这个命令之后就行了:
@echo off
echo hahahhahahhahha
pause
但你想要输出中文的时候,却可能会发现输出的是乱码。
乱码的根本原因是啥?就是保存的编码格式与读取的编码格式不同!电脑一般为ANSI编码,而目前记事本默认使用的utf-8编码。
更多原理,可以参考本站的这篇文章:编码。
所以只需要将文件另存为ansi
编码即可:
在记事本中,可以按快捷键Ctrl+Shift+S
弹出“另存为”窗口,然后就可以选择编码了。
3.5 变量(set)
既然脚本被称为语言,那就肯定会有变量,但脚本语言中的变量与我们平时在C/C++中所使用的有点不一样。
批处理中的变量都是通过set
命令来指定的:
@echo off
set msg=www.kucoding.com
echo %msg%
pause
只需要通过=
赋值即可,同时要注意=
前后不要有空格,否则会出错。
而输出就用前面提到的echo
命令,注意变量的使用要用两个%
包起来,不然echo
命令无法识别这是一个变量,而将它直接当做一个字符串处理的。
但这样只能赋值字符串,我们有时候想要计算,需要保存数字怎么办呢?
还是set
命令,使用/a
参数即可:(注意,windows
命令参数通过 /
,而linux参数通过-
表示)
@echo off
set /a a=10
set /a b=20
set /a c=%a%+%b%
echo %c%
pause
上面设置了两个变量,然后相加,最后输出相加结果:
当然乘除也是可以的,但注意除的精确度并不高,使用的也较少。
除了上面这种自己设置变量,自己使用外,我们有时候可能还需要接受用户输入的参数:
比如C/C++
中的main
函数,可以接受用户输入的参数。
事实上批处理中同样可以,通过%
后面紧跟数字,即可表示用户输入的第几个参数,比如:
@echo off
echo %1
echo %2
echo %3
pause
上面的命令就是直接输出用户输入的前三个参数:
然后我先自己启动一个控制台,再执行这个文件,其后跟着参数即可,就能正常输出了!
还有另一种需求,那就是我们需要获取用户的输入, 通过指定/p
参数即可:
@echo off
set /p a=请输入a值:
set /p b=请输入b值:
set /a c=%a%+%b%
echo %c%
pause
当添加了/p
参数,=
符号之后的内容就是提示语了,用起来也还是很简单。
效果如下:
更多关于set命令的使用方法,可以在控制台中输入set /?
获取。
3.6 判断(if)
除了使用变量外,判断语句也很常见。
使用方法就是 if 判断语句 (为真执行的内容) else (为假执行的内容)
比如下面:
@echo off
set a=abcd
set b=acbd
if %a%==%b% (echo a与b相等) else (echo a与b不相等)
pause
注意,只有==
这个符号可以被使用,其用处就是判断两个字符串是否相等,诸如>,<
这些符号是没有用的,会出错。
如果你想要使用其它判断操作,需要用到下面的操作符:
操作 | 功能 |
---|---|
equ | 等于 |
neq | 不等于 |
lss | 小于 |
leq | 小于等于 |
gtr | 大于 |
geq | 大于等于 |
比如上面的==
就可以改写为:
if %a% equ %b% (echo a与b相等) else (echo a与b不相等)
注意其后要执行的命令,最好都加上()
当然,如果你觉得上面这样写不好看,可以改写为:
if %a% equ %b% (
echo a与b相等
) else (
echo a与b不相等
)
这样就可以在判断完成后的执行语句中,多写几行命令
注意:因为else
关键字必须在if
这行命令的最后,所以想要分行写,那个(
必须写在if
这一行的最后,意味着if语句并未结束、还需要继续读取下一行的内容,不能将(
也另起一行,否则就会出错。
下面这样写就是错的:
if %a% equ %b%
(
echo a与b相等
) else
(
echo a与b不相等
)
这个(
必须在if
这一行的最后,新手很容易犯这个错误,又由于批处理文件很难调试出错误,很容易让人学着学着就放弃了。
最后就是记住这个格式,下次直接就这样用就行了。
除了基本的判断以外,它还可以判断文件是否存在,添加关键词exist
即可,其后跟文件名:
if exist filename
比如判断文件1.bat
是否存在:
if exist 1.bat (
echo 1.bat文件存在
) else (
echo 1.bat文件不存在
)
如果文件名存在空格,记得要加双引号""
将文件名括起来。
除了判断基本数据,和上面的文件是否存在外,它还可以判断上一个命令的退出码。
也就是我们写C/C++语言时,main函数中我们的return
语句,返回的那个数值,有时候我们没有写这个return
语句,却没有报错,那是因为编译器帮我们补上了的,并不是不需要。
if errorlevel 1 (
echo 退出码大于等于1
) else (
echo 退出码小于1
)
如上所示,当上一个命令的退出码大于等于1时,为真。
当然上面这么用起来,会很麻烦,一般我们更习惯于直接获取这个值来判断:%errorlevel%
上面的代码意思就是,获取上一个命令(关闭回显这个命令)的退出码,是否等于0
一般来说,退出码为0时,为正确执行,否则命令执行出错。
更多详细的用法,可以在控制台输入if /?
获取。
3.7 循环(for)
接下来要介绍的就是循环语句,使用方法与在C/C++
中同样也有较大区别,它在批处理中是一个非常重要且复杂的命令。
其基本结构为:
for %%i in (集合) do (
:要执行的命令语句
)
比如:
for %%i in (1,2,3,4) do (
echo %%i
)
效果如下:
注意for语句中,有三个关键字不可或缺 for,in ,do
,for
与in
之间的就是变量名,前面需要有两个%
表示,后面在do
后紧跟的执行命令中要使用这个变量,也需要这样使用。
然后是in
和do
之间的就是要遍历的东西,我这里写的4个数字,中间用,
隔开。
这里同样注意,上面这个写法基本是固定的,不要尝试更改do
的位置,以及其后紧跟的(
符号,也不要另其一行。
整句的意思也很明显,就是变量i,遍历(1,2,3,4)
,然后执行do
后的语句,通过echo
命令,循环输出。
当然上面那种写法比较麻烦,比如我想要循环1
到100
怎么办呢?
那就需要给for
命令添加参数:/L
(大小写均可)
然后in
后的范围就可以像下面这样写:
(开始,每次增值,结束)
(1,1,100)
即从1
开始,每次添加1
,直到100
结束: