了解Windows批处理文件与Perl的system()函数的交互

时间:2012-01-03 10:17:34

标签: perl

BATCH文件的一个例子:

@echo off
echo starting
setlocal
cd c:\tmp
set A=B
perl -e "$ENV{X}='Y'; system('cmd')"
echo finished

我运行此脚本(在Windows 7上),并在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>

我知道我有两个炮弹跑,交替得到我的输入:  一个工作目录设置为C:\,另一个设置为C:\tmp

知道这里发生了什么吗?拥有Windows 7的人可以用他/她的Perl版本试用我的示例批处理脚本吗?顺便说一句,我使用Perl 5.8.8运行它,因为这是在这个项目中使用的版本。

1 个答案:

答案 0 :(得分:0)

是的,我看到了同样的行为。 Ctrl + C以某种方式通过前景cmd.exe获取并应用于父perl进程,该进程可能被杀死(取决于Y / N回答perl与批处理作业一起被杀死)。当cmd处于交互模式时,它通常会忽略Ctrl + C,因此它似乎是泄漏到父进程的错误。

旁注:结果是你留下了两个cmd shell试图读取()单个终端输入。一旦读取一行,他就会处理它,另一行会跳入并有机会读取()下一行。等等。

解决方法是告诉perl忽略SIGINT:

perl -e "$SIG{INT} = 'IGNORE'; ... "

您需要使用exit来完成前景cmd,而不是Ctrl + C.