• call


    -------siwuxie095

     

     

     

    call

    调用另一个批处理程序或自身程序段,调用完,程序会回到原来 call 的地方继续执行

    如果在脚本或批处理文件外使用 call,则不会在命令行起作用

     

     

    语法

    call  [[Drive:][Path] FileName [BatchParameters]]   [:Label [Arguments]]

     

     

    参数说明:

     

    [Drive:][Path] FileName

    指定要调用的批处理程序的位置(路径)和名字,FileName 参数必须有 .bat .cmd 扩展名

     

    BatchParameters

    指定批处理程序所需的任何命令行信息,包括命令行选项、文件名、批处理参数

    (即从 %0%9)或 变量(如 %baud%

     

    call :Lable Arguments

    调用本文件内命令段(目标程序段),相当于子程序。

    (1)被调用的命令段以标签  :label 开头,goto :eof 结尾,调用完回到原来 call 的地方

              继续执行下去。

    (2)假如被调用的命令段(子程序) exit 结尾,调用完子程序后就会直接退出,

              不会回到原来 call 的地方。

    (3)假如被调用的命令段没有 goto :eof  或 exit 等退出标志,程序在调用子程序后,

              会一直执行到整个程序末尾,然后才会回到原来 call 的地方继续执行下去。

     

     

    Arguments

    对于以 :Label 开始的批处理程序,指定要传递给其新实例的所有命令行信息,包括

    命令行选项、文件名、批处理参数(即 %0%9) 或 变量(如 %baud%

     

     

     

    注意事项:

    不要在 call 命令中使用管道重定向符号。

     

    可以创建调用自身的批处理程序,但是必须提供退出条件,

    否则父子程序将循环上千次

     

    在启用命令扩展的情况下(即默认情况下),call 将接受 Label 参数作为

    调用目标,语法:

    call :Label Arguments

    call  [Drive:][Path] FileName

     

     

    如: 测试.bat  调用桌面上 test 文件夹内的  goto.bat

     

    image        image

     

     

    sublime中:

     

    image

     

    image

     

     

    测试效果一览:

     

    image

     

     

     

     

    再如:同一文件夹下的 a.bat 和 b.bat 

    @echo off
    set /p var=请选择(Y/N):
    if /i "%var%"=="Y" call b.bat
    echo a.bat 执行完毕
    pause >nul

     

    @echo off
    echo Hello World
    start explorer.exe
    echo b.bat 执行完毕
    pause >nul

     

     

    sublime中:

     

    image       image

     

     

    运行 a.bat 后,效果一览(同时还打开了 资源管理器):

     

    image

     

     

     

    子程序语法:

    :label

    command1

    command2

    commandn

     

    子程序段中,参数 %0 指标签 :label

     

    在主程序中,注意使用 goto     exit      goto :eof  等跳转语句,避免

    误进入其他子程序

     

    主程序和子程序中的所有变量都是全局变量,作用范围是整个批处理程序

     

    主程序传递至子程序的参数在call语句中指定,在子程序中用 %0%9

    形式调用,子程序返回主程序的数据只需在调用结束后,直接引用即可 

     

    如:test.bat

    @echo off
    set /p a=请输入一个数字 :
    if /i %a%==0 (call :o ) else (call :t)
    :o
    echo Hello World
    pause>nul & exit
    :t
    echo This is a bat program
    pause>nul & exit

     

     

    sublime中:

     

    image

     

     

    运行效果一览:

     

    image

     

     

     

    goto call

     

    虽然都可以跳转,但说到底,goto 只是跳转而已,跳转到目的地后,

    程序按顺序执行下去,不会返回原来的地方。call 调用完程序段后还会

    返回原来 call 的地方继续执行下去。

     

    call 调用程序段还可以给参数,goto 则不能。

     

     

    如:A.bat  和  B.bat

    @echo off
    echo 早上好
    goto noon
    echo 晚安
    pause
    :noon
    echo 中午好
    :night
    echo 晚上好
    pause

     

    @echo off
    echo 早上好
    call :noon
    echo 晚安
    pause
    :noon
    echo 中午好
    :night
    echo 晚上好
    pause

     

     

    sublime中:

     

    image         image

     

     

    运行效果一览:

    A.bat                                                  B.bat

    image                        image

     

     

    显然,call 不会像 goto 那样打断流程,它只是暂时中断了当前流程

    而跳转到目标程序段执行,目标程序段执行完毕,仍回到原来 call

    地方继续执行下去。所以 call 后经常会有 goto :eof  exit 等退出语句

     

    如:

    @echo off
    set var=123
    call :loop
    pause>nul & goto :eof
    :loop
    set /a var+=1
    echo var=%var%
    pause>nul

     

    sublime中:

     

    image

     

    如果没有 goto :eof,则会显示两次数据

    @echo off
    set var=123
    call :loop
    pause>nul
    :loop
    set /a var+=1
    echo var=%var%
    pause>nul

     

    比较:

     

    image    image

     

     

     

     

    call 带参数:

    如:

    @echo off
    call :an Hello 世界
    :an
    echo %1
    echo %2
    pause>nul

     

    sublime中:

     

    image

     

    运行一览:

     

    image

     

     

    再如:

    @echo off
    call :sub return 你好
    echo 子程序返回值 :%return%
    echo %0
    pause>nul
    :sub
    set %1=%2
    echo %0

     

    sublime中:

     

    image

     

     

    运行一览:

     

    image

     

     

    主程序里 %0 表示主程序的完整路径,即 "C:UserssiwuxDesktop estx.bat"

     

    子程序里 %0 表示子程序的完整路径,即 :sub

     

    对于子程序中的 return 参数,子程序运行结束,主程序可以直接使用,return

    全局有效

     

    注意,主程序里不能用 %1- %9 的形式调用子程序参数

    如(此调用无效):

    @echo off
    call :sub return 你好
    echo %1
    echo %2
    pause>nul
    :sub
    set %1=%2

     

     

    再如:多数据求和

    @echo off
    set sum=0
    call :sub sum 10 20 30
    echo 数据求和结果: %sum%
    pause>nul
    goto :eof
    :sub
    set /a %1=%1+%2
    shift /2
    if not "%2"=="" goto sub

     

     

    sublime中:

     

    image

     

     

    运行一览:

     

    image

     

     

     

    再如: a.bat 自我调用

    call a.bat

     

    sublime中:

     

    image

     

    运行 a.bat,被执行 1241 次

     

     

     

     

    再如:call 带参数----斐波那契数列

    @echo off
    setlocal enabledelayedexpansion
    echo. & echo 斐波那契数列
    echo.
    echo 请输入数列总项数
    set /p num=(DOS 计算能力不够强大 ,输入的数字不要超过 46):
    echo. & echo --------------------------------------------------------------
    if %num% gtr 46 echo. & echo 输入数据太大 ,按任意键退出 & pause >nul & exit
    set /a e=!num!-2
    set a=1
    set b=1
    set c=2
    if %num% geq 1 call :shuchu !a!
    if %num% geq 2 call :shuchu !b!
    for /l %%i in (1,1,%e%) do (
    set /a temp=!a!+!b!
    set /a c+=1
    set /a d=!c!%%5
    call :shuchu !temp!
    if !d!==0 echo.
    set a=!b!
    set b=!temp!
    )
    echo. & echo. & echo 输出结束 ,按任意键退出 & pause>nul
    ::这里要注意退出 ,否则程序会继续执行后面的:shuchu 程序段
    goto :eof
    :shuchu
    set f= %1
    echo.
    set /p pr=!f:~-11!<nul

     

    sublime中:

     

    image

     

    运行一览:

     

    image

     

     

    程序有多个地方用到输出语句,而一个输出就要用到下面两句,用call调用函数来简化

    set f= %1
    set /p pr=!f:~-11!<nul

     

     

     

    %0 往往代表自身

     

    批处理中 %* 指出所有的参数(如 %0   %1%n

     

    关于 %1的扩展(~代表扩展、扩充、增强等):

     

    %~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 的输出行

     

     

    %1PATH 可以被其它有效数值替换。

    %~ 语法被一个有效参数值终止(如 1 2 3 …)

    %~ 不能和 %* 一起使用

     

    如:

    @echo off
    call :sub temp.txt
    pause & exit
    :sub
    echo 删除引号: %~1
    echo 扩充到路径: %~f1
    echo 扩充到一个驱动器号: %~d1
    echo 扩充到一个路径:%~p1
    echo 扩充到一个文件名: %~n1
    echo 扩充到一个文件扩展名: %~x1
    echo 扩充的路径只含有短名: %~s1
    echo 扩充到文件属性: %~a1
    echo 扩充到文件的日期/时间: %~t1
    echo 扩充到文件的大小: %~z1
    echo 查找列在 PATH 环境变量的目录,并将第一个参数扩充到找到的第一个完全合格的名称: %~$PATH:1
    echo 扩展到驱动器号和路径: %~dp1
    echo 扩展到文件名和扩展名: %~nx1
    echo 扩展到类似 DIR 的输出行: %~ftza1

     

    sublime中:保存 testx.bat 到桌面

     

    image

     

    (1)桌面上没有temp.txt,运行一览:

     

    image

     

     

    (2)桌面上新建一个 temp.txt,文件属性和运行一览:

     

    image

     

    image

     

     

    (3)桌面没有temp.txt,F盘新建一个temp.txt,同时修改代码:

    @echo off
    call :sub F:	emp.txt
    pause & exit
    :sub
    echo 删除引号: %~1
    echo 扩充到路径: %~f1
    echo 扩充到一个驱动器号: %~d1
    echo 扩充到一个路径:%~p1
    echo 扩充到一个文件名: %~n1
    echo 扩充到一个文件扩展名: %~x1
    echo 扩充的路径只含有短名: %~s1
    echo 扩充到文件属性: %~a1
    echo 扩充到文件的日期/时间: %~t1
    echo 扩充到文件的大小: %~z1
    echo 查找列在 PATH 环境变量的目录,并将第一个参数扩充到找到的第一个完全合格的名称: %~$PATH:1
    echo 扩展到驱动器号和路径: %~dp1
    echo 扩展到文件名和扩展名: %~nx1
    echo 扩展到类似 DIR 的输出行: %~ftza1

     

     

    文件属性和运行一览:

     

    image

     

    image

     

     

     

     

     

    call 高级技巧:

     

    一、嵌套和递归:

     

    如:

    汉诺塔问题:n个盘子和3根柱子:A(源)、B(中转)、C(目的)

    开始n个盘子从上往下从小到大叠在A柱上(即大盘在下,小盘在上

    要将盘子从A柱移动到C柱,移动过程中可以使用B柱,且只能移动

    最顶端的盘子,且盘子只能放在比它本身大的盘子上(即始终保持

    大盘在下,小盘在上),且一次只能移动一个盘子

    @echo off
    title 汉诺塔(Hanoi)
    echo. & echo.
    echo 汉诺塔程序
    setlocal enabledelayedexpansion
    echo. & set /p plate=请输入盘子数量 :
    echo. & echo -----------------------------
    call :move !plate! A B C
    echo -----------------------------
    echo. & echo 运算结束 ,按任意键退出 & pause>nul
    :move
    if %1==1 (echo 盘子从 %2 柱子移动到 %4 柱子) else (
    set i=%1
    set /a i-=1
    call :move !i! %2 %4 %3
    echo 盘子从 %2 柱子移动到 %4 柱子
    set j=%1
    set /a j-=1
    call :move !j! %3 %2 %4
    )

     

    sublime中:

     

    image

     

     

    运行一览:

     

    image

     

     

    call 递归,嵌套层级测试:

    @echo off
    call :loop 1
    :loop
    echo %1>>temp.txt
    set /a n=%1+1
    call :loop %n%

     

    sublime中:

     

    image

     

     

     

    不用 call 也能实现嵌套,批处理中有一个很特殊的参数 %0

    本身可以带参数运算(和 call 类似)

    如:从1开始,每次加1,无限…

    @echo off
    set /a var=%1+1
    echo %var%
    %0 %var%

     

    用call的话(同上):

    @echo off
    :loop
    set /a var=%1+1
    echo %var%
    call :loop %var%

     

     

    call %0 的区别:

     

    call 有迭代层级限制,而 %0 没有迭代层级限制

     

    call 调用完程序后会回到原来 call 的地方继续执行,即 call 可以

    实现递归,而 %0 仅仅重复调用自身,即 %0 不能实现递归

     

    call 可以只调用程序中的某一小段程序,而 %0 只能调用自身整个程序

    在有延迟变量的情况下,%0 调用没几次就达到极限,不能继续执行,

    所以 %0 无法实现复杂的程序调用

     

     

     

    二、用 call 实现延迟功能

     

    代码1:

    @echo off
    set str=www.cn-dos.net
    set n=4
    echo %%str:~%n%%%
    pause>nul

     

    代码2:

    @echo off
    set str=www.cn-dos.net
    set n=4
    call echo %%str:~%n%%%
    pause>nul

     

     

    sublime中:

     

    image      image

     

    运行一览:

     

    image      image

     

     

    代码一并不能得到:cn-dos.net,而是显示: %str:~4%这是因为cmd

    中存在预处理机制,读取:echo %%str:~%n%%% 时,先是迫不及待的脱

    最外层的 %,变为:echo %str:~%n%%,即第二层的 % 变成了字符 %

    自然最后就显示%str:~4%

    代码二通过 call 的延时作用,延时后,cmd会一层层脱去 %,并解释 %

    的变量,就能正确显示:cn-dos.net

     

     

     

    三、call 邪法

     

    @echo off
    set a=dos
    set b=a
    set c=b
    set d=c
    echo %a%
    call echo %%%b%%%
    call call echo %%%%%%%c%%%%%%%
    call call call echo %%%%%%%%%%%%%%%d%%%%%%%%%%%%%%%
    pause>nul

     

    sublime中:

     

    image

     

     

    有 n 个 call 时,需要 2^(n+1)-1%

     

     

     

    【made by siwuxie095】

  • 相关阅读:
    javascript的自定义对象
    解决trim兼容性
    AJAX
    javascript中的默认对象
    js原始数据类型
    javascript的内置对象
    空判断啊
    javascript的继承
    html如何设置P的高度为零?
    asp.net 生成静态页 自动分页
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6225526.html
Copyright © 2020-2023  润新知