为什么在 "set /p" 提示时使用 Ctrl+C 取消 Windows 批处理脚本会产生不一致的行为?

Why does canceling a Windows batch script with Ctrl+C when prompted by "set /p" give inconsistent behavior?

这是脚本 foo.cmd :

@echo off
echo hi
set /p foobar="???"
echo bye

set /p 提示时,我按 Ctrl+C 取消脚本。此时,似乎随机选择了几种可能的事情之一:

  1. ^C 出现,然后是 Terminate batch job (Y/N)?
  2. ^C 出现,然后是 The syntax of the command is incorrect. 然后脚本终止,没有回显 bye.
  3. ^C 出现,脚本继续,回显 bye

我也见过像 1 或 2 这样的情况,但是 ^C 出现在“终止”提示或语法错误消息之后。

连续三次尝试的实际输出:

    C:\Users\Me\Documents>foo.cmd
    hi
    ???^CThe syntax of the command is incorrect.
    
    C:\Users\Me\Documents>foo.cmd
    hi
    ???^Cbye
    
    C:\Users\Me\Documents>foo.cmd
    hi
    ???^CTerminate batch job (Y/N)? y
    
    C:\Users\Me\Documents>

我发现了一个 7 年前的相关问题,但答案没有解释为什么会这样:set /p reads ctrl+c as input instead of terminating the script

set /pcmd 内部是等待输入的命令之一。 CTRL+C 意味着停止进程正在内部杀死 set /p 进程。

正如另一个内部进程 timeout 所证明的那样,结果是相似的,但有一个实例 ^C 字符由换行符分隔。这个批处理文件只包含 timeout /t 5 然后我在其中随机执行 CTRL+C

为了证明 CTRL+C 正在杀死您示例中的内部进程,然后是主进程,我们可以在脚本本身中创建 CTRL+C(所有功劳都归功于用户 DBenham for the exit code 创建 ^C:

@echo off
echo hi
set /p foobar="???" || cmd /c exit -1073741510
echo bye

当 运行 执行此操作并在 set /p 提示符下按 Enter 时,将完成 set 命令,直接在 ^C 发出后。每个 运行 的结果将保持不变,因为 CTRL+C 只有主要进程要关闭: