【问题标题】:In this batch script, why doesn't control reach the echo statement?在这个批处理脚本中,为什么控制不到 echo 语句?
【发布时间】:2022-01-09 07:40:13
【问题描述】:

我有 test1.bat、test2.bat、test3.bat,内容如下:

echo %0

因此我有 test.bat:

test1.bat > t1 && test2.bat > t2 && test3.bat > t3
echo done with test?.bat invocation
set /p t1=<t1
set /p t2=<t2
set /p t3=<t3
del t1 t2 t3
echo %t1% %t2% %t3%
echo done

这会导致没有显示任何 echo 语句,但是会创建文件 t1、t2 和 t3。它们不会被删除。

【问题讨论】:

    标签: windows batch-file cmd


    【解决方案1】:

    这行得通:

    test1.bat > t1 && test2.bat > t2 && test3.bat > t3
    

    什么时候改成

    call test1.bat > t1 && call test2.bat > t2 && call test3.bat > t3
    

    不过,我不确定为什么调用语句真的很有必要。我想我还有第二个问题,当我不使用 call 语句时会发生什么?

    【讨论】:

    • 如果您只是执行另一个批处理文件,您会将控制权转移给它 - 并且控制权将永远不会返回到正在执行的实例。如果你call一个批处理文件,一旦被调用的批处理文件结束,它将被执行并将控制权转移回调用实例。
    • @gk_2000,我刚刚阅读了已被另一位成员删除的信息,(已编辑)。然而,我不得不说,我对他们的编辑没有任何问题,我自己也会这样做。请不要质疑投反对票,除非投反对票的人专门告诉你他们这样做的原因。也请不要要求人们投票。
    • 好吧,我必须阅读 Dave 和 Jeb 在 How does the Windows Command Interpreter (CMD.EXE) parse scripts? 上的精彩问答,但似乎合乎逻辑的是,由于所有代码行在执行之前都被解释,因此文件流在代码被执行。所以当这行代码开始执行时,所有的文件都会被创建。
    • 所有三个test?.bat 都被执行,因为解析器已经将它们“放在内存中”(它们在一行上),但最后一个结束时没有将控制权返回给主脚本。跨度>
    • 我同意@Compo,你不应该在你的问题中添加结尾段落。它既不需要也不提供与问题的任何相关性。
    【解决方案2】:

    除非您使用call 运行另一个批处理文件,否则执行控制不会在被调用批处理文件完成后返回到调用批处理文件。这解释了为什么不执行脚本的后续命令。

    您的情况有点棘手,因为您从单个命令行运行多个批处理文件:

    test1.bat > t1 && test2.bat > t2 && test3.bat > t3
    

    现在当一个批处理文件被执行时,它不会作为一个整体存储在内存中,而是从批处理文件中读取每一行,然后缓冲。在解析期间,首先要做的事情之一是标记化和重定向处理,其中&amp;&amp;&gt; 被识别1

    您似乎知道,&amp;&amp; 运算符仅在前一个命令成功时才允许执行以下命令,这意味着它的 exit code 为零。

    现在整个缓冲行被执行,但是由于缺少call,执行控制不会返回给调用者,所以被调用者的退出代码也不会报告回来,因此所有三个子脚本都将是无条件地一个接一个地跑。


    实验

    以下实验说明了上述声明。

    在每个test?.bat 文件中只输入一个命令@exit /B #,并将# 替换为文件名? 中的数字减一(例如,test1.bat 包含@exit /B 0)。

    然后执行:

    test1.bat > t1 && test2.bat > t2 && test3.bat > t3
    

    会有t12t3三个文件,返回的退出码不被识别。

    现在执行:

    call test1.bat > t1 && call test2.bat > t2 && call test3.bat > t3
    

    只有t1t2这两个文件,返回的退出码确实被识别了。


    1) 详情请参考此综合贴:How does the Windows Command Interpreter (CMD.EXE) parse scripts?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多