CMD与DOS脚本编程【第四章】
预计更新
第一章. 简介和基础命令
1.1 介绍cmd/dos脚本语言的概念和基本语法
1.2 讲解常用的基础命令和参数,如echo、dir、cd等
第二章. 变量和运算符
2.1 讲解变量和常量的定义和使用方法
2.2 介绍不同类型的运算符和运算规则
第三章. 控制流程和条件语句
3.1 介绍if、else、for、while等控制语句的用法
3.2 讲解条件语句的语法和应用场景
第四章. 函数和参数传递
4.1 讲解如何定义和调用函数以及传递参数
4.2 介绍函数的作用域和递归调用
第五章. 文件操作
5.1 讲解如何创建、读取、写入和删除文件
5.2 介绍文件操作的常用命令和参数,如copy、del、type等
第六章. 环境变量和系统信息
6.1 介绍环境变量的概念和设置方法
6.2 讲解如何获取系统信息,如系统时间、用户名等
第七章. 网络通信和远程控制
7.1 介绍如何使用cmd/dos脚本语言进行网络通信
7.2 讲解如何使用远程控制命令,如telnet、net等
第八章. 错误处理和调试技巧
8.1 介绍常见的错误类型和处理方法
8.2 讲解如何使用调试工具和技巧
第九章. 脚本编写和调试实战
9.1 提供一些实际案例,让读者通过编写和调试脚本来加深理解和掌握技能
9.2 讲解如何测试和优化脚本性能
第十章. 其他高级主题和扩展
10.1 讲解其他高级主题,如正则表达式、批处理、交互式命令等
10.2 介绍如何扩展和定制cmd/dos脚本语言的功能和特性
第四章. 函数和参数传递4.1 讲解如何定义和调用函数以及传递参数4.2 介绍函数的作用域和递归调用
讲解如何定义和调用函数以及传递参数
本文将深入讲解在 cmd 和 DOS 脚本语言编程中如何定义和调用函数以及传递参数的方法和技巧。我们将从函数的概念和语法开始,讨论函数的定义、调用和返回值的使用。然后,我们将介绍参数的传递方式和如何在函数中使用它们。最后,我们将通过实例来演示如何使用函数和参数来编写实际的脚本程序。
一、函数的概念和语法
在 cmd 和 DOS 脚本语言中,函数是一组可重用的代码块,用于完成特定的任务。函数可以接受输入参数并返回值。函数的定义格式如下:
:label
command1
command2
...
goto :eof
其中,:label 是函数的名称,可以由用户自定义,但必须以冒号开头。command1、command2 等是函数的主体,用于执行特定的任务。goto :eof 表示函数的结束,其中 :eof 是 cmd 中预定义的标签,表示文件的末尾。
为了调用函数,我们需要在脚本中使用函数名称加上参数列表的形式来调用函数。例如:
call :functionName parameter1 parameter2 ...
其中,call 是 cmd 中调用函数的关键字,functionName 是函数的名称,parameter1、parameter2 等是函数的输入参数。
二、函数的定义和调用
函数的定义是编写脚本程序的重要部分,正确的定义可以使代码更加清晰和易于维护。下面是一个简单的函数定义示例:
:myFunction
echo "This is my function."
goto :eof
在上述示例中,我们定义了一个名为 myFunction 的函数,函数主体中使用 echo 命令输出了一条消息。goto :eof 表示函数结束,这也是 cmd 中标准的函数结束方式。
要调用函数,我们需要在脚本中使用 call 命令,并指定需要调用的函数名称和输入参数。下面是一个调用 myFunction 函数的示例:
call :myFunction
在上述示例中,我们使用 call 命令调用了 myFunction 函数。因为我们在函数定义中没有定义任何输入参数,所以在调用函数时不需要传递任何参数。
三、函数的返回值
在函数中,我们可以使用 set 命令来设置函数的返回值。下面是一个简单的函数定义示例,该函数返回传递的第一个参数:
:returnValue
set returnValue=%1
goto :eof
在上述示例中,我们定义了一个名为 returnValue 的函数,函数主体中使用 set 命令设置了返回值为传递的第一个参数。在函数结束时,我们使用 goto :eof 命令表示函数结束。
在调用函数时,我们可以使用 %returnValue% 的形式来访问函数的返回值。下面是一个示例,展示了如何调用 returnValue 函数并访问其返回值:
call :returnValue parameter1
echo The return value is %returnValue%.
在上述示例中,我们使用 call 命令调用了 returnValue 函数,并传递了一个参数 parameter1。然后,使用 %returnValue% 访问函数的返回值,并使用 echo 命令输出。
需要注意的是,在函数中设置的变量只能在函数内部使用,无法在函数外部访问。如果需要在函数外部访问函数的返回值,可以使用 setlocal 和 endlocal 命令来设置局部变量。
四、函数的参数传递
在 cmd 和 DOS 脚本语言中,函数支持两种类型的参数传递方式:位置参数和命名参数。
- 位置参数
位置参数是指在函数调用时按照顺序传递的参数,它们的顺序对应着函数定义中的参数顺序。下面是一个示例,展示了如何在函数中使用位置参数:
:sum
set /a result=%1+%2
goto :eof
在上述示例中,我们定义了一个名为 sum 的函数,函数主体中使用 set /a 命令计算传递的前两个位置参数的和,并将结果保存在 result 变量中。在函数结束时,我们使用 goto :eof 命令表示函数结束。
在调用函数时,我们可以按照顺序传递参数。下面是一个示例,展示了如何调用 sum 函数并传递两个位置参数:
call :sum 3 5
echo The result is %result%.
在上述示例中,我们使用 call 命令调用了 sum 函数,并传递了两个位置参数 3 和 5。然后,使用 %result% 访问函数的返回值,并使用 echo 命令输出。
需要注意的是,在函数中使用位置参数时,可以使用 %1、%2 等来访问它们。例如,在上述示例中,我们可以使用 %1 和 %2 来访问传递的位置参数。
- 命名参数
命名参数是指在函数调用时使用名称和值的形式传递的参数。命名参数可以使代码更易于阅读和维护,因为它们不依赖于参数的顺序。下面是一个示例,展示了如何在函数中使用命名参数:
:concat
set concatResult=%param1%%param2%
goto :eof
在上述示例中,我们定义了一个名为 concat 的函数,函数主体中使用 set 命令将传递的两个命名参数按顺序拼接在一起,并将结果保存在 concatResult 变量中。在函数结束时,我们使用 goto :eof 命令表示函数结束。
在调用函数时,我们可以使用名称和值的形式传递参数。下面是一个示例,展示了如何调用 concat 函数并传递两个命名参数:
call :concat param1=Hello param2=World
echo The result is %concatResult%.
在上述示例中,我们使用 call 命令调用了 concat 函数,并传递了两个命名参数 param1=Hello 和 param2=World。然后,使用 %concatResult% 访问函数的返回值,并使用 echo 命令输出。
需要注意的是,在函数中使用命名参数时,可以使用 %param1%、%param2% 等来访问它们。例如,在上述示例中,我们可以使用 %param1% 和 %param2% 来访问传递的命名参数。
五、实例演示
为了更好地理解如何定义和调用函数以及传递参数,下面我们将演示一个实际的脚本程序。该脚本程序可以计算一个文本文件中每个单词出现的次数,并将结果输出到另一个文件中。
首先,我们需要定义一个函数来计算单词出现的次数。该函数需要接受一个文件名作为输入参数,并返回一个包含单词出现次数的关联数组。下面是函数定义的代码:
:countWords
setlocal enabledelayedexpansion
set inputFile=%1
for /f "tokens=1" %%i in ('type !inputFile! ^| findstr /r /c:"^[^ ]"') do (set word=%%iset /a words[!word!]+=1
)
endlocal & set words=%words%
goto :eof
在上述代码中,我们定义了一个名为 countWords 的函数,函数主体中使用setlocal enabledelayedexpansion 命令启用了延迟扩展,这样我们就可以在循环中使用 ! 来访问变量,而不是 %。
函数主体中使用 for 命令遍历文件中的每个单词,并使用 set /a 命令将其添加到关联数组 words 中。在循环结束后,我们使用 endlocal & set words=%words% 命令将关联数组传递回调用者。最后,我们使用 goto :eof 命令表示函数结束。
接下来,我们需要定义另一个函数来将单词出现次数输出到文件中。该函数需要接受两个参数:一个包含单词出现次数的关联数组和一个输出文件名。下面是函数定义的代码:
:outputWordCount
setlocal enabledelayedexpansion
set outputFile=%2
(for /f "tokens=1,2 delims==" %%i in ('set words') do (echo %%i=%%j
)) > %outputFile%
endlocal
goto :eof
在上述代码中,我们定义了一个名为 outputWordCount 的函数,函数主体中使用 for 命令遍历关联数组 words 中的每个元素,并使用 echo 命令将其输出到文件中。在循环结束后,我们使用 endlocal 命令结束本地化环境,并使用 goto :eof 命令表示函数结束。
现在我们已经定义了两个函数,可以在脚本程序中调用它们来计算单词出现次数并将结果输出到文件中。下面是脚本程序的完整代码:
@echo offset inputFile=input.txt
set outputFile=output.txtcall :countWords %inputFile%
call :outputWordCount %words% %outputFile%echo Done.goto :eof:countWords
setlocal enabledelayedexpansion
set inputFile=%1
for /f "tokens=1" %%i in ('type !inputFile! ^| findstr /r /c:"^[^ ]"') do (set word=%%iset /a words[!word!]+=1
)
endlocal & set words=%words%
goto :eof:outputWordCount
setlocal enabledelayedexpansion
set outputFile=%2
(for /f "tokens=1,2 delims==" %%i in ('set words') do (echo %%i=%%j
)) > %outputFile%
endlocal
goto :eof
在上述代码中,我们定义了两个变量 inputFile 和 outputFile,分别表示输入文件名和输出文件名。然后,我们调用 countWords 函数计算单词出现次数,并将结果保存在 words 变量中。接着,我们调用 outputWordCount 函数将单词出现次数输出到文件中。最后,我们使用 echo 命令输出消息表示程序执行完成,并使用 goto :eof 命令表示程序结束。
需要注意的是,在调用函数时,我们使用 %1、%2 等来访问位置参数,并使用 %words% 和 %outputFile% 来访问变量。在函数定义中,我们使用 !inputFile! 和 !word! 来访问变量,这是因为在函数中启用了延迟扩展。
总结一下,函数是一种模块化编程的技术,可以将代码分解为可重用的部分,从而提高代码的可维护性和可读性。在批处理脚本中,我们可以使用 call 命令定义和调用函数,并使用位置参数或命名参数传递参数。
介绍函数的作用域和递归调用
在CMD和DOS脚本语言中,函数作为模块化编程的基本单元,可以分解代码为可重用的部分,从而提高代码的可维护性和可读性。在本文中,我们将介绍函数的作用域和递归调用,以帮助读者更好地理解和使用函数。
一、函数的作用域
作用域是指变量和函数的可见范围。在CMD和DOS脚本语言中,函数的作用域与变量的作用域是相同的,都遵循静态作用域规则。
静态作用域规则指的是变量和函数的作用域在编译期间就已经确定,而不是在运行期间动态确定。具体来说,函数内部可以访问全局变量和函数,但全局变量和函数不能访问函数内部的局部变量和函数。
下面是一个示例代码,演示了函数的作用域规则:
@echo offset globalVar=globalcall :func1
echo globalVar=%globalVar%
goto :eof:func1
set localVar=local
set globalVar=modified
echo localVar=%localVar%
goto :eof
在上述代码中,我们定义了一个全局变量 globalVar 和一个函数 func1。在 func1 中,我们定义了一个局部变量 localVar,并修改了全局变量 globalVar 的值。在主程序中,我们调用 func1 并输出全局变量 globalVar 的值。
运行上述代码,输出结果如下:
localVar=local
globalVar=modified
可以看到,函数 func1 可以访问全局变量 globalVar,并修改了它的值。但是,主程序不能访问函数 func1 中的局部变量 localVar。
二、递归调用
递归调用是指函数直接或间接调用自身的过程。在许多算法和数据结构问题中,递归调用是一种比较自然和简洁的解决方案。在CMD和DOS脚本语言中,函数也支持递归调用。
下面是一个示例代码,演示了递归调用的实现:
@echo offset /a n=5call :factorial %n% resultecho %n%! = %result%
goto :eof:factorial
if %1==0 (set /a %2=1
) else (set /a n=%1-1call :factorial %n% tempset /a %2=%1*temp
)
goto :eof
在上述代码中,我们定义了一个函数 factorial,它计算一个正整数的阶乘,并存储结果在参数 %2 中。在函数中,我们使用递归调用实现了阶乘的计算过程。
具体来说,我们首先判断参数 %1 是否为0,如果是,则将参数 %2 设为1,表示阶乘的结果为1。如果参数 %1 不为0,则将参数 %1 减1,并调用函数 factorial 计算参数 %1 的阶乘。在递归调用返回后,我们将参数 %2 设为 %1 与计算结果的乘积,从而得到参数 %1 的阶乘。
运行上述代码,输出结果如下:
5! = 120
可以看到,我们成功地使用递归调用实现了阶乘的计算。
需要注意的是,递归调用可能会导致栈溢出等问题,因此在设计和使用递归调用时需要谨慎。在CMD和DOS脚本语言中,由于缺乏语言层面的优化和支持,递归调用的效率可能较低,尤其是对于大规模的计算任务。因此,在实际编程中,我们需要根据具体的问题需求和程序性能考虑是否使用递归调用。
三、总结
在本文中,我们介绍了函数的作用域和递归调用在CMD和DOS脚本语言中的使用。函数的作用域遵循静态作用域规则,即函数内部可以访问全局变量和函数,但全局变量和函数不能访问函数内部的局部变量和函数。递归调用是一种比较自然和简洁的解决方案,但也需要注意可能导致的栈溢出等问题。在实际编程中,我们需要根据具体的问题需求和程序性能考虑是否使用递归调用。
相关文章:
CMD与DOS脚本编程【第四章】
预计更新 第一章. 简介和基础命令 1.1 介绍cmd/dos脚本语言的概念和基本语法 1.2 讲解常用的基础命令和参数,如echo、dir、cd等 第二章. 变量和运算符 2.1 讲解变量和常量的定义和使用方法 2.2 介绍不同类型的运算符和运算规则 第三章. 控制流程和条件语句 3.1 介…...
Liunx安装Docker
Liunx在线安装Docker 简介: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不…...
docker:容器的数据卷
1 数据卷概念及作用 1.1 什么是容器数据卷 先来看看Docker的理念: 将应用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的容器之间希望有可能共享数据 Docker容器产生的数据,如果不通过…...
【TCP】对TCP三次握手的个人理解
三次握手 TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。三次握手的过程如下图: 一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态 …...
squid的基本代理
一、Squid代理服务器的概述 squid 作为一款服务器代理工具,可以缓存网页对象,减少重复请求,从而达到加快网页访问速度,隐藏客户机真实IP,更为安全。 Squid主要提供缓存加速、应用层过滤控制的功能 1、squid代理的工…...
【从零开始写视觉SLAM】v0.1基于特征点的简单VO
v0.1版本的oSLAM实现了基于orb特征点的简单视觉里程计,通过连续两帧的rgbd数据实现相机相对位姿的估计。 #mermaid-svg-ibQfHFVHezQD5RWW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ibQfHFVHezQD5RW…...
CentOS-7 安装 MariaDB-10.8
一、安装之前删除已存在的 Mysql/MariaDB 1 查找存在的 MariaDB # 注意大小写 rpm -qa | grep MariaDB # rpm -qa 列出所有被安装的rpm package (-qa:query all) rpm -qa | grep mariadb # grep (缩写来自Globally search a Regular Expre…...
Packet Tracer – 对 VLAN 实施进行故障排除 – 方案 1
Packet Tracer – 对 VLAN 实施进行故障排除 – 方案 1 地址分配表 设备 接口 IP 地址 子网掩码 交换机端口 VLAN PC1 NIC 172.17.10.21 255.255.255.0 S2 F0/11 10 PC2 NIC 172.17.20.22 255.255.255.0 S2 F0/18 20 PC3 NIC 172.17.30.23 255.255.255.0…...
五、c++学习(加餐1:汇编基础学习)
经过前面几节课的学习,我们在一些地方都会使用汇编来分析,我们学习汇编,只是学习一些基础,主要是在我们需要深入分析语法的时候,使用汇编分析,这样会让我们更熟悉c编译器和语法。 从这节课开始,…...
iOS正确获取图片参数深入探究及CGImageRef的使用(附源码)
一 图片参数的正确获取 先拿一张图片作为测试使用 图片参数如下: 图片的尺寸为: -宽1236个像素点 -高748个像素点 -色彩空间为RGB -描述文件为彩色LCD -带有Alpha通道 请记住这几个参数,待会儿我们演示如何正确获取。 将这张图片分别放在…...
Typescript 5.0 发布:快速概览
探索最令人兴奋的功能和更新 作为一种不断发展的编程语言,TypeScript 带来了大量的改进和新功能。在本文中,我们将深入探讨 TypeScript 的最新版本 5.0,并探索其最值得关注的更新。 1. 装饰器 TypeScript 5.0 引入了一个重新设计的装饰器系…...
【图像处理 】卡尔曼滤波器原理
目录 一、说明 二、它是什么? 2.1 我们可以用卡尔曼滤波器做什么? 2.2 卡尔曼滤波器如何看待您的问题...
YOLOv5 实例分割入门
介绍 YOLOv5 目标检测模型以其出色的性能和优化的推理速度而闻名。因此,YOLOv5 实例分割模型已成为实时实例分割中最快、最准确的模型之一。 在这篇文章中,我们将回答以下关于 YOLOv5 实例分割的问题: YOLOv5检测模型做了哪些改动,得到了YOLOv5实例分割架构?使用的 Prot…...
数字城市发展下的技术趋势,你知道多少?
提到数字城市、智慧城市大家都会感觉经常在耳边听到,但是要确切说出具体的概念还是有一点难度的。具体来说:数字城市是一个集合多种技术的系统,以计算机技术、多媒体技术和大规模存储技术为基础,以宽带网络为纽带,运用…...
linux 串口改为固定
在/etc/udev/rules.d 目录下新建定义规则的文件 1. 文件名要按规范写否则改动无效2. 规则文件必须以.rules 结尾3. 规则文件名称必须遵循 xx-name.rules 格式(xx 为数字或字母,name 为规则名称),例如 99-serial-ports.rules。4. 规…...
【SCI一区】考虑P2G和碳捕集设备的热电联供综合能源系统优化调度模型(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Redis缓存数据库(四)
目录 一、概述 1、Redis Sentinel 1.1、docker配置Redis Sentinel环境 2、Redis存储方案 2.1、哈希链 2.2、哈希环 3、Redis分区(Partitioning) 4、Redis面试题 一、概述 1、Redis Sentinel Redis Sentinel为Redis提供了高可用解决方案。实际上这意味着使用Sentinel…...
View中的滑动冲突
View中的滑动冲突 1.滑动冲突的种类 滑动冲突一般有3种, 第一种是ViewGroup和子View的滑动方向不一致 比如: 父布局是可以左右滑动,子view可以上下滑动 第二种 ViewGroup和子View的滑动方向一致 第三种 第三种类似于如下图 2.滑动冲突的解决方式 滑动冲突一般情况下有2…...
java boot项目基础配置之banner与日志配置演示 并教会你如何使用文档查看配置
上文 我们简单讲了一下 springboot 项目的配置 都是写在resources下的application.properties中 springboot 项目中 配置都写在这一个文件 可以说非常方便 不像之前 写个项目配置这里一个哪里一个 看到是非常费力 我们启动项目 这里有个图案 其实 这叫 banner 我们就用配置来…...
蓝鲸平台通过标准运维 API 安装 Agent
目录 一、背景 二、目的 三、创建安装agent流程 四、通过标准运维 API 安装 Agent 五、总结 一、背景 蓝鲸平台正常情况纳管主机需要在节点管理手工安装agent,不能达到完成自动化安装agent的效果。想通过脚本一键安装agent,而不需要在蓝鲸平台进行过…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
