BATCH文件示例:
@echo off
echo starting
setlocal
cd c:tmp
set A=B
perl -e "$ENV{X}='Y'; system('cmd')"
echo finished
我运行这个脚本(在Windows7上),工作目录设置在c:.
中正如预期的那样,脚本打开了一个新的命令shell,工作目录设置为c:tmp
,环境设置为脚本中定义的环境。
作为下一步,我在这个shell中执行了Control-C,其中要求我执行Terminate batch job (Y/N)?.
用Y,
回答这个问题时,我得到的错误消息是:
'Y' is not recognized as an internal or external command, operable program or batch file.
但是,我得到一个shell提示,当前目录显示为c:tmp
。假设我再次键入Control-C。现在我看到:
c:tmp>^C
finished
c:>
我的提示显示我的工作目录回到了C: However
,这个shell显示了一个有趣的行为。如果我在这个shell中反复点击ENTER
,我得到以下输出:
c:>
c:tmp>
c:>
c:tmp>
更进一步,我知道我有两个shell在运行,交替地得到我的输入:一个工作目录设置为C:
,另一个为C:tmp
。
知道这里发生了什么吗?有人能用他的Perl版本试用一下我的示例批处理脚本吗?顺便说一句,我使用Perl 5.8.8运行它,因为这是本项目中使用的版本。
是的,我看到了同样的行为。Ctrl+C以某种方式通过前台cmd.exe并应用于父perl进程,该进程可能会被终止(取决于Y/N答案,perl与批处理作业一起被终止)。当cmd处于交互模式时,它通常会忽略Ctrl+C,因此它泄漏到父进程似乎是一个错误。
附带说明:结果是,只剩下两个cmd shell试图读取()单个终端输入。只要一个人读到一行,他就会处理它,另一个人就会跳进去,有机会读()下一行。等等。
解决方法是告诉perl忽略SIGINT:
perl -e "$SIG{INT} = 'IGNORE'; ... "
您需要使用exit
来完成前台cmd,而不是使用Ctrl+C。