本章节主要介绍 call 命令的使用:
call 是一个功能强大的命令,它不但可在批处理程序中调用另一个批处理程序,而且还可调用指定标号处后面的所有命令(也可以称为子程序)。语法如下:
CALL [drive:][path]filename [batch-parameters]
参数说明:
[Drive:] 指定被调用批处理文件的盘符
[Path] 指定被调用批处理文件路径
FileName 指定被调用的批处理文件名,当被调用的批处理文件与正在执行的批处理文件都处于同一目录下时,可以省略盘符及路径;
batch-parameters 指定批处理程序所需的命令行参数信息;
/? 在命令提示符显示帮助;
实例:创建两个批处理文件,分别为 test.bat 和 sub.bat。在 test.bat 中调用 sub.bat,不传递任何参数信息。
(1)test.bat 文件内容:
@echo off echo test.bat call sub.bat call C:\Users\Administrator\Desktop\sub.bat pause
(2)sub.bat 文件内容:
@echo off echo sub.bat
输出结果:
C:\Users\Administrator\Desktop> test.bat test.bat sub.bat sub.bat 请按任意键继续. . .
实例:创建两个批处理文件,分别为 test.bat 和 sub.bat。在 test.bat 中调用 sub.bat,传递参数信息。
(1)test.bat 文件内容:
@echo off echo test.bat call sub.bat arg1 arg1 call C:\Users\Administrator\Desktop\sub.bat arg1 arg1 pause
(2)sub.bat 文件内容:
@echo off echo sub.bat echo 第一个参数:%1 echo 第二个参数:%2
输出结果:
C:\Users\Administrator\Desktop> test.bat test.bat sub.bat 第一个参数:arg1 第二个参数:arg1 sub.bat 第一个参数:arg1 第二个参数:arg1 请按任意键继续. . .
如果命令扩展被启用,CALL 会如下改变,CALL 命令可以调用指定标签后面的语句(即调用子程序)。语法是:
CALL :label [arguments]
参数说明:
:label 用于指定调用位置的标签,与goto语句中使用的标签类似;
arguments 对于以 :label 开头的批处理程序(或子程序),指定要传送给其新实例的命令行信息,包括命令行选项、文件名、批处理参数或者变量;
/? 在命令提示符显示帮助;
实例:在批处理脚本中创建 :sub 标签,然后使用 call :sub 调用该标签。
@echo off echo test.bat call :sub goto end :sub echo sub label goto :eof :end pause
输出结果:
C:\Users\Administrator\Desktop> test.bat test.bat sub label 请按任意键继续. . .
实例:在批处理脚本中创建 :sub 标签,然后使用 call :sub arg1 arg2 调用该标签, 并且指定参数。
@echo off echo test.bat call :sub arg1 arg2 goto end :sub echo sub label echo 第一个参数:%1 echo 第二个参数:%2 goto :eof :end pause
输出结果:
C:\Users\Administrator\Desktop> test.bat test.bat sub label 第一个参数:arg1 第二个参数:arg2 请按任意键继续. . .
另外,批脚本文本参数(%0、%1、等等)已如下改变:
(1)批脚本里的 %* 指出所有的参数(如 %1 %2 %3 %4 %5 ...),实例:
test.bat 文件内容:
@echo off echo test.bat call sub.bat arg1 arg2 pause
sub.bat 文件内容:
@echo off echo sub.bat echo 参数:%*
输出结果:
C:\Users\Administrator\Desktop> test.bat test.bat sub.bat 参数:arg1 arg2 请按任意键继续. . .
(2)批处理参数(%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 可以被其他有效数值替换。%~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %* 使用。
实例:生成一个临时文件 tmp.txt,先将目录 C:\windows 设置为当前目录,调用子程序进行参数扩展;然后再恢复当前目录,调用子程序;观察参数扩展结果。
@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
输出结果:
C:\Users\Administrator\Desktop> test.bat 删除引号: tmp.txt 扩充到路径: c:\Windows\tmp.txt 扩充到一个驱动器号: c: 扩充到一个路径: \Windows\ 扩充到一个文件名: tmp 扩充到一个文件扩展名: .txt 扩充的路径指含有短名: c:\Windows\tmp.txt 扩充到文件属性: 扩充到文件的日期/时间: 扩充到文件的大小: 扩展到驱动器号和路径:c:\Windows\ 扩展到文件名和扩展名:tmp.txt 扩展到类似 DIR 的输出行:c:\Windows\tmp.txt 删除引号: tmp.txt 扩充到路径: C:\Users\Administrator\Desktop\tmp.txt 扩充到一个驱动器号: C: 扩充到一个路径: \Users\Administrator\Desktop\ 扩充到一个文件名: tmp 扩充到一个文件扩展名: .txt 扩充的路径指含有短名: C:\Users\ADMINI~1\Desktop\tmp.txt 扩充到文件属性: --a------ 扩充到文件的日期/时间: 2020/06/16 13:21 扩充到文件的大小: 19 扩展到驱动器号和路径:C:\Users\Administrator\Desktop\ 扩展到文件名和扩展名:tmp.txt 扩展到类似 DIR 的输出行:--a------ 2020/06/16 13:21 19 C:\Users\Administrator\Desktop\tmp.txt 请按任意键继续. . .
运行下面这段call代码会死循环,楼主帮我看看
goto _start
:system
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
cd /d "%~dp0"
goto :eof
:_start
call :system
echo 楼主!楼主!
pause
exit
这是因为 :system 子程序中的 goto :eof 语句没有起到跳出循环的作用,goto :eof 语句作用如下:
(1)在无call的情况下,会直接退出批处理,此时等同于exit
(2)在call的情况下,会中止call,继续执行其他命令
注意:读者不要轻易运行该脚本,该脚本将重复 “关闭旧DOS窗口,打开新DOS窗口”。
goto :eof 语句作用如下:
(1)在无call的情况下,会直接退出批处理,此时等同于exit
(2)在call的情况下,会中止call,继续执行其他命令
代码里有call,为什么没有终止call,按逻辑来看,加了goto:eof会终止call然后输出:楼主!楼主!
而他是直接死循环,很不理解,代码放下面了:
goto _start
:system
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
cd /d "%~dp0"
goto :eof
:_start
call :system
echo 楼主!楼主!
pause
exit
主要是这行代码:
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
影响到 goto :eof 语句,具体原因不是很清楚,可以去找资料,找到后希望留言,学习学习!!