【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法

一、执行CMD命令的3种方式

执行CMD命令的两种方式分别是手动创建一个Cmd窗口和执行bat批处理文件。

第一种,先手动创建一个cmd窗口,然后往里面输入cmd命令,最后回车执行。

第二种,先在一个bat文件中键入cmd命令,保存代码后,双击执行。

第三种,先在一个bat文件中键入cmd命令,保存代码后,在手动创建的cmd窗口中用命令执行bat文件。

二、批处理命令中的参数——%0、%1、...、%9、%*

何谓批处理命令中的参数?

在手动创建的Cmd窗口中直接执行命令是没有参数可言的,只有在手动创建的cmd窗口中执行bat批处理文件才有参数。

因为%0-%9都是形式参数,如果没有赋值,就是普通字符串,所以下面在手动创建的cmd窗口中echo出来的都是原文本。如果把%0-%9比作10个指针,当没有指向一个数值时,就是普通字符串。

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第1张图片

往bat文件中输入参数的格式如下:bat_filepath arg1 arg2 ... argx(bat_filepath表示第0个参数,对应%0,arg1表示第x个参数,对应%1,以此类推,参数与参数之间用空格或制表符分隔)。

假设 【d:\D-desktop】中有3个bat文件——main.bat、main1.bat、demo.bat。

demo.bat文件中的代码如下:

chcp 65001
@echo off
echo %0
echo %~0
echo %~f0
echo %1
echo %2
pause

在当前目录为【d:\D-desktop】的情况下,执行命令【demo main.bat main1.bat】。

结果如下,我们可以看到五行输出中,demo对应%0,于是echo %0的输出是demo,而main.bat对应%1、main1.bat对应%2,于是echo %1和echo %2的输出是main.bat和main1.bat。

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第2张图片

至于第2行的echo %~0和第3行的echo %~f0,涉及到参数扩展的知识,我们在第五章详细铺开。

那什么是%*呢?

%*代表全部的批处理参数,也即代表%1-%9整体,不同参数之间用空格分隔。

在main.bat文件中添加下面的代码,在cmd命令窗口执行命令【main.bat 123 456】。

@echo off
chcp 65001
echo %0
echo %1
echo %2
echo %*
pause

输出结果如下。

 【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第3张图片

在bat脚本中直接执行【%0】或通过call命令调用%0,都会导致Bat文件陷入没有尽头的死循环。

@echo off
chcp 65001
echo "大哥出生了"&echo "二弟出生啦"&echo "三妹出生啦"
(
echo "大哥出生了"
echo "二弟出生啦"
echo "三妹出生啦"
)
call %0
pause

你们可以把上面这块代码复制到bat文件中,双击执行试试,绝对会不断地“生孩子”哈哈哈。 

三、批处理参数和3种执行方式

在本文第一章提到对cmd命令的3种执行方式(小生不才,可能还有更多种执行方式哈哈哈,但是本文只讨论这3种)。

第一种属于非批处理脚本执行方式,没有参数可言。

第二种和第三种属于批处理脚本执行方式。

第二种无法手动输入参数,但是有参数的意义,一般来说只有%0这一个参数,默认就是bat文件的完整路径。

但是,有些BAT文件中如果执行call命令的时候,不管是内部调用还是外部调用,只要后面加了参数,就至少给指针%1赋予了数据。

举个例子。

main.bat的代码(type %1下面还有一个空行,不然最后执行时第2个echo=的空行效果会被抑制)如下所示:

@echo off
echo %0
echo %~f0
echo=
call :end D:\D-desktop\demo.bat
pause
:end
type %~f0
echo=
type %1

demo.bat的代码(echo %2下面还有一个空行,不然最后type完了,主程序的pause提示信息会接在echo %2上)如下所示:

chcp 65001
@echo off
echo %0
echo %~0
echo %~f0
echo %1
echo %2

双击执行main.bat文件,结果如下所示:

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第4张图片

我们可以发现demo.bat文件的路径参数被传至了主程序的%1中,也由此可见call命令进行内部调用时,批处理参数从%1开始计量。

第三种可以手动输入参数,与第二种执行方式不同的是%0这个参数根据执行bat文件时所用命令的输入形式有关,其中第1个输入值直接原本不动地转化为%0,可能会覆盖默认的完整路径。

举个例子,demo.bat文件在路径【D:\D-desktop】中。假设执行cmd命令【demo.bat】,那么%0就等于【demo.bat】。而如果是直接双击(也可以是其他非cmd命令执行方式),那么%0就是等于【D:\D-desktop\demo.bat】。

四、批处理参数和shift命令

第二章我们知道形式参数一共有10个,分别是%0、%1、...、%9,但是实际我们可能会需要输入大于10的参数数量,如何实现呢?

这就要提到本章节的主人翁——shift命令。

4.1 打印shift命令的帮助信息

执行【shift /?】。

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第5张图片

一句话,shift命令专门用来偏移批处理参数和输入参数值之间的对应关系。

帮助文档对shift命令的简述是“更改批处理文件中可替换参数的位置” ,显然没有我的总结更加准确直观。

而shift命令的唯一参数就是/n,n指的是起始偏移位置。例如n=2时,只有%x(x>=2)的指针才需要偏移。

4.2  shift命令作用机制的直观呈现

4.2.1 不带参数的shift命令——shift

假设初始状态下(如下引用块所示),cmd为bat脚本文件名,可以用%0引用。

cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
   |      |      |       |       |      |       |       |       |      |        |

 %0   %1  %2   %3   %4  %5   %6    %7   %8  %9    

经过1次shift后,cmd将无法被引用,因为没有一个指针指向它。 

cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
          |      |       |      |       |       |      |       |       |       |
        %0   %1   %2  %3   %4   %5  %6    %7   %8   %9

 经过2次shift后,arg1也被废弃,%9指向为空,也没有意义。

cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                  |      |       |       |       |      |       |       |      |
                %0   %1   %2   %3   %4  %5   %6   %7   %8  

4.2.2 带参数n的shift命令——shift /n

假设初始状态下(如下引用块所示),cmd为bat脚本文件名,可以用%0引用。

cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
   |      |      |       |       |      |       |       |       |      |        |

 %0   %1  %2   %3   %4  %5   %6    %7   %8  %9    

执行一次shift /2,因为起始偏移位置设置成2,因此%0和%1都原地待命,%2-%9才需要向右偏移。这时候,arg2参数值成为了没有指针指向的对象。

cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
   |      |      |       |       |      |       |       |       |      |        |

 %0   %1         %2   %3   %4   %5   %6    %7  %8   %9    

再执行一次shift /2,arg2和arg3全没指针引用,%9指针也没有指向一个参数值。

cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
   |      |      |       |       |      |       |       |       |      |        |

 %0   %1                  %2   %3   %4   %5  %6  %7    %8 

五、参数(指针)的扩展形式

很有意思的一点,批处理参数的扩展帮助文本,竟然是靠执行【call /?】获得的,call命令和批处理参数关系真不一般。

5.1 获得call命令的帮助信息——call /?

d:\D-desktop>call /?
从批处理程序调用另一个批处理程序。

CALL [drive:][path]filename [batch-parameters]

  batch-parameters   指定批处理程序所需的命令行信息。

如果命令扩展被启用,CALL 会如下改变:

CALL 命令现在将卷标当作 CALL 的目标接受。语法是:

    CALL:label arguments

一个新的批文件上下文由指定的参数所创建,控制在卷标被指定
后传递到语句。你必须通过达到批脚本文件末两次来 "exit" 两次。
第一次读到文件末时,控制会回到 CALL 语句的紧后面。第二次
会退出批脚本。键入 GOTO /?,参看 GOTO :EOF 扩展的描述,
此描述允许你从一个批脚本返回。

另外,批脚本文本参数参照(%0、%1、等等)已如下改变:


     批脚本里的 %* 指出所有的参数(如 %1 %2 %3 %4 %5 ...)

     批参数(%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 可以被其他有效数值替换。
    %~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %*
    使用

d:\D-desktop>

5.2 提取和转化

5.2.1 %0和%~0的区别

如果%0对应的值不被引号包括,那么就没有任何区别,但是如果被引号包围,用%~0就能去除引号。

下图是双击执行main.bat文件的结果。

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第6张图片

 5.2.2 各个简写的记忆技巧.

d对应drive——驱动器

f对应filepath——文件路径(包括文件名)

p对应path——路径(不包括文件名)

n对应name——文件名

x对应Ext——扩展名

a对应attribute——属性

z对应siZe——大小

5.2.3 $PATH:的含义

%~$PATH:1——查找列在 PATH 环境变量的目录,并将 %1扩展到找到的第一个完全合格的名称。如果环境变量名未被定义,或者没有找到文件,此修改符会扩展到空字符串。

从帮助信息很容易理解它的含义,但是当我双击执行结果正常、而用CMD命令执行结果却不正常时,我就迷糊又懵逼了。

详见本文的第六章,作为高难度部分,希望各位读者能和我一起想出这个问题的答案!

六、一些没有解决的问题放在最后,一起探讨?

6.1 双击执行bat文件和在cmd窗口用命令执行输出结果不同

bat文件代码如下

chcp 65001
@echo off
echo %0
echo %~0
echo %~dp0
echo %~f0
echo %~fs0
echo %~n0
echo %~s0
echo %~a0
echo %~t0
echo %~$PATH:0
echo %~dp$PATH:0
pause

6.1.1 直接执行bat文件 

直接执行,结果如下图,不能说正常,只能说完全正常好吧???

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第7张图片

6.1.2 命令执行bat文件

在cmd窗口通过命令执行(除了bat文件名本身,没有赋予其他参数), 结果如下。明显最后的echo %~$PATH:0和echo %~dp$PATH:0的输出结果出现异端,非常诡异。

 【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第8张图片

 6.1.3 问题适当联想 

当bat文件代码如下所示

chcp 65001
@echo off
echo %0
echo %~0
echo %~f0
echo %1
echo %2
pause

不仅包括%0,还有%1和%2时, 直接双击执行bat文件,结果如下图

【批处理DOS-CMD命令-汇总和小结】-批处理命令中的参数%0、%1、%2、%[0-9]、%0-9和批处理命令参数位置切换命令shift,dos命令中操作符%用法_第9张图片

因为双击执行时除了%0其他的批处理参数都没有值,所以涉及到的参数全部输出ECHO is off。

你可能感兴趣的:(Cmd和Dos,windows,cmd,dos)