批处理脚本整不明白那你可能要处处被处理

批处理脚本整不明白那你可能要处处被处理批处理(`Batch`,简称 `bat`)是一系列 `Dos` 命令按照一定的顺序组成的一个可执行文件,后缀名是 `.bat` 或者 `.cmd`,其常用于 `Dos` 或者 `Windows` 系统

批处理(Batch,简称 bat)是一系列 Dos 命令按照一定的顺序组成的一个可执行文件,后缀名是 .bat 或者 .cmd,其常用于 Dos 或者 Windows 系统,通常我们是指 Dos 脚本。

本文我们主要讲解批处理的基本命令,掌握这些内容基本就可以顺畅看懂常用的批处理脚本,最后再以 vscode 源码中用于启动项目的 code.bat 脚本实战一下。下面我们就从最熟悉的,基本上大家都见到过的 echo 开始吧!

echo

在批处理中echo用于输出信息,默认会将命令本身也输出。创建 index.bat 文件中添加如下所示代码:

echo hello
pause

双击运行 index.bat 脚本后可以看到如下图所示内容:

image.png

可以看到通过 echo 输出了指定的内容,pause 是暂停命令并且输出了一句 “请按任意键继续” ,不然终端运行完成后直接退出就看不到效果了。值得注意的是 echo 命令本身也被输出了,如果要关闭批处理命令本身的输出可以通过 @echo off 设置从此行开始往后不再输出批处理命令本身,出发遇到了 @echo on 重新开启输出命令本身 (如果遇到了中文乱码的问题请往后看):

:: 设置不再输出命令本身
@echo off

:: 输出hello字符
echo hello

:: 暂停
pause

image.png

这里的 ::vscode 中表示的是注释,:: 后面跟着注释内容。注释还可以使用 @rem表示:

:: comments

@rem comments

如果在编码 bat 脚本时需要用到中文,则在使用 vscode 时有可能会遇到中文乱码问题,其他的比如记事本或者 notepad++ 不会。在 vscode 中编写带中文的 bat 文件需要做一些编辑器设置。首先我们写个带中文的 bat 脚本如下所示:

:: 中文注释
@echo off

:: 输出中文内容到一个中文名称的文件中
echo 你好 > 你好.txt

pause

首先需要确认换行符是CRLF(如果是 windows 系统)和编码格式是 GBK的,如下图所示:

image.png

如果不是则需要设置成 GBKCRLF。然后在面板中将打开 bat 文件的编码格式也设置成 GBK 的,这样以后打开 bat 文件都是 GBK 了,不然默认打开都是以 utf8 预览的,这样就会看到乱码。

image.png

image.png

配置都完成后我们再重新打开编辑 bat 脚本,然后保存运行尝试,发现运行和预览都正常了,如下图所示:

image.png

输出重定向

  • > 将内容输出到指定的位置,比如写入到指定文件,输出到空设备、控制台等。值得注意的是>是覆盖输出:
@echo off

:: >命令是覆盖输出
echo 123 > hello.txt
:: 456会覆盖123内容
echo 456 > hello.txt

pause
  • >>命令可以做到追加输出,比如:
@echo off

:: >>命令是追加输出
echo 123 >> hello.txt
:: 456会追加在123后面
echo 456 >> hello.txt

pause

set

在批处理中 set 命令是用来查看、设置和移除环境变量的。

使用 set 命令不加任何参数可以查看所有的环境变量,set key=value 的形式的设置环境变量,key 是变量名,value 是变量值。

@echo off
:: 设置环境变量
set envVarName=envVarValue

:: 查看所有环境变量
set

:: 查看环境变量名称为envVarName开头的环境变量
set envVarName

pause

image.png

set 命令使用 /A 参数可以让右值支持表达式写法:

@echo off

set demoEnv=123
:: demoEnv2的值是3
set /A demoEnv2=1+2
:: demoEnv2的值是126,是demoEnv变量的值加demoEnv2的值的结果
set /A demoEnv3=%demoEnv% + %demoEnv2%
set demoEnv

pause

image.png

set 命令赋值是右侧内容为空则可以移除环境变量,如下所示:

image.png

使用 setlocalendlocal 命令可以划分一个局部作用域,在该作用域内设置的变量不会影响到外部的环境变量:

image.png

文件路径相关

%~dp0 获取脚本文件所处文件目录, %cd% 获取当前脚本执行所处环境的文件目录:

@echo off

:: 获取脚本文件所在文件目录
echo %~dp0

:: 获取当前脚本执行所处环境的文件目录
echo %cd%

pause

image.png

除此之外,如下更多获取文件路径等相关命令如下:

image.png

字符串处理

  • 字符串截取

使用 %变量名:~下标, 字符数% 可以截取环境变量的值的子字符串,~ 指定截取字符串的开始位(从 0 开始),, 后面的参数指定截取的字符数:

image.png

  • 字符串替换

%变量名:替换目标=替换内容% 命令可以替换字符串,注意 : 后面的空格也会表示一个字符,因此要小心添加空格。如果要移除指定内容,则将要替换的字符串不设置值即可,如下所示:

@echo off

set demoEnv=abcade
:: 输出bcde
echo %demoEnv:a=%

set demoEnv2=abc
:: 输出 ffbc
echo %demoEnv2:a=ff%
pause

for循环

for 命令用于对一组字符串或者文件执行某些命令,会依次提取每个元素将值赋给指定的变量,然后对运行执行 do 后面的命令。%% 符号是在 for 循环中设置和获取变量的语法。基本格式如下所示:

@echo off
:: 循环一组字符串
for %%i in (HELLO,WORLD) do (
   echo %%i
)
pause

image.png

for 命令可以遍历一组文件,可以使用通配符 * 表示所有文件。注意,如果echo输出的内容含有特殊字符则需要使用 ^ 对特殊字符进行转义,如下所示:

@echo off

:: 遍历当前目录下所有文件
:: 也可以使用类似aa.*等的格式
for %%a in (*) do (
   :: 输出迭代内容
   echo ^|--%%a
)

pause

image.png

for 命令的 /F 参数可以用来处理文件内容或者一些命令的返回结果,可以提取文件内容进行逐行分析处理。基本命令格式如下:

for /F "指定命令的参数" in (文件或者命令) do (
  :: 待运行的命令
)

假设有一个 hello.txt 文件,文件内容如下图所示:

image.png

下面演示读取 hello.txt 文本内容按行遍历,使用空格分割每行内容,提取分割后的第一列和第二列子字符串进行输出:

image.png

/F 参数的内容如下所示:

  • delims 指定分割内容,可以指定多个分隔符,比如delims=|:;指定了使用竖线、冒号和分号进行分割,如果包含空格则要把空格放在最后
  • tokens 指定如何提取分割后的子字符串,tokens=n,m,z指定提取第 n 例、第 m 列和第 z 列,tokens=m-n指定提取第 m 列到第 n 列,提取的子字符串会赋值给指定的环境变量(例如这里的 %%a),并且会依次递增赋值给%%b%%c,一直到 %%z
  • skip=n 指定解析文件时从文件头部跳过的行数
  • eol=c 指定忽略以指定字符开头的行数

如果 for 循环处理的文件名包含空格,则需要使用双引号包裹起来。

code.bat实战

:: 从当前行开始不显示命令本身
@echo off

:: 设置局部作用域
setlocal

:: 设置控制台标题
title VSCode Dev

:: 记录项目根路径的位置
:: pushd记录位置,后续执行popd命令时跳转回该位置
:: %~dp0表示脚本文件所在文件目录的位置,\..表示再上一层目录
pushd %~dp0\..

:: Get electron, compile, built-in extensions
:: 预启动
:: 如果变量 VSCODE_SKIP_PRELAUNCH 不存在,执行 node build/lib/preLaunch.js命令
:: 注意:在.vscode/settings.json中配置了files.exclude字段指定不显示的内容
::      因此在vscode中看不到build/lib/preLaunch.js文件,其内容是build/lib/preLaunch.ts编译后的产物
if "%VSCODE_SKIP_PRELAUNCH%"=="" node build/lib/preLaunch.js

:: 从product.json文件中提取nameShort字段的值(Code - OSS),该值实则是electron.exe的名称
:: findstr从product.json文件中提取含有 "nameShort":.* 格式的行
::    /R表示把后面的参数作为表达式使用,/C:"xxx"表示指定的字符串包含的空格不能作为分隔符
:: for循环迭代筛选的行,`delims=:,`按分号或逗号分割字符串,`token=2`提取分割结果的第二项
::    将提取结果赋值给变量a,设置环境变量NAMESHORT的结果为环境变量a,%%~a中的~表示去掉所有的引号
for /f "tokens=2 delims=:," %%a in ('findstr /R /C:"\"nameShort\":.*" product.json') do set NAMESHORT=%%~a

:: 去除NAMESHORT变量的所有 空格引号 两个字符
set NAMESHORT=%NAMESHORT: "=%
:: 去除NAMESHORT变量的所有引号,并且在后面拼接.exe字符
set NAMESHORT=%NAMESHORT:"=%.exe
:: 拼接CODE变量值为electron的程序路径
set CODE=".build\electron\%NAMESHORT%"

:: Manage built-in extensions
:: 调用code.bat时第一个参数传递的是--builtin则跳转到下面builtin的位置处执行
if "%~1"=="--builtin" goto builtin

:: Configuration
:: 配置环境变量
set NODE_ENV=development
set VSCODE_DEV=1
set VSCODE_CLI=1
set ELECTRON_ENABLE_LOGGING=1
set ELECTRON_ENABLE_STACK_DUMPING=1

:: Launch Code
:: 程序启动的代码
:: 调用electron程序执行根目录下文件,会自动获取package.json中指定的main字段作为启动入口
:: main字段指定的为./out/main,该文件由src/main.js编译而来
%CODE% . %*
goto end

:builtin
%CODE% build/builtin

:end

:: 跳转回pushd记录的位置,即项目根目录
popd

endlocal

这里的基本命令相信大家都看得明白,code.bat 脚本是 vscode 源码的项目启动脚本,这个脚本主要做了两件事:

  • 执行一个 node build/lib/preLaunch.js 命令执行预启动相关的内容
  • 根据 product.json 中的 nameShort 字段找到真实的 electron 启动程序的位置,运行该程序(类似于 electron your/main/emtry

今天的文章批处理脚本整不明白那你可能要处处被处理分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13951.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注