什么可能导致Perl系统调用开始失败?

时间:2012-06-18 13:59:39

标签: windows perl

一个小小的请求:我每天都会阅读Stack Overflow的Perl问题,并尽可能地回答/贡献;今天我需要社区的帮助!

Perl设置:我在Windows上运行Active Perl 5.8.8。安装位于我们部门服务器的本地驱动器上,该驱动器也与网络共享。所有部门用户都通过指向这个网络安装的Perl在自己的PC上运行Perl。这已经工作了多年,并没有引起问题,但这是了解问题所需的一条信息。

有问题的服务器也是我们的“cron”(计划任务)服务器,处理各种自动化任务。上周突然间,Perl脚本(服务器上)的系统调用开始失败(详情如下)。起初,我怀疑Perl安装已损坏,但所有客户端PC仍然可以运行相同的Perl脚本而没有任何问题,这让我觉得这是一个服务器问题。我重新启动了服务器两次,问题仍然存在,因此我需要帮助!

以下是系统调用失败的各种方式的一些示例,归结为Perl单行:

% perl -e "system('dir')"

那应该打印一个“dir”列表,而是打开一个子shell。如果我输入“exit”,我可以退出子shell,然后我回到原始shell中(通过使用向上箭头键检查shell历史记录来确认)。

% perl -e "print `dir`"

这实际上是挂起的。什么都没发生。如果我按Ctrl-C来终止进程,我收到消息“终止信号SIGINT(2)”,然后DOS提示返回。但是,DOS提示符中的任何未来命令(甚至只是命中ENTER)都会导致错误“进程尝试写入不存在的管道。”。你必须退出DOS提示符,因为它实际上没用。

最后一个例子:

% perl -e "system('Z:/Scripts/rebuild.pl')"

'ebuild.pl'未被识别为内部或外部命令, 可操作程序或批处理文件。

在这种情况下,Perl将正斜杠(/)切换到DOS / Windows反斜杠(),它已经做好了多年。但是,Perl将“rebuild.pl”文件名开头的“\ r \ n”解释为回车符(我认为)并查找剩余的“ebuild.pl”。调用其他脚本名称,其字符不能被误解为导致上面的挂起(如果你使用反引号)打开子shell(对于system()调用)。

我不只是对此感到困惑 - 我很绝望!我们部门服务器的“cron”作业现在没用,因为我们使用了大量的系统调用。

同样,我不认为这是一个损坏的Perl安装,因为网络用户可以正常运行。那么,可能会导致Perl系统调用失败的单个机器(不依赖于Perl安装本身)会发生什么?

环境设置,按要求:

ALLUSERSPROFILE=C:\Documents and Settings\All Users
APPDATA=C:\Documents and Settings\engmodem\Application Data
CDSROOT=Z:\Cadence\SPB_16.5
CDS_CONCEPT_NOSPLASH=TRUE
CDS_LIC_ONLY=1
CDS_SITE=Z:\Cadence\Sites\16.5
CHDL_LIB_INST_DIR=%CDSROOT%
CLIENTNAME=USENTUTTLJL3C
ClusterLog=C:\WINDOWS\Cluster\cluster.log
CommonProgramFiles=C:\Program Files\Common Files
COMPUTERNAME=CORPUSAPP5
ComSpec=C:\WINDOWS\system32\cmd.exe
CONCEPT_INST_DIR=%CDSROOT%
FP_NO_HOST_CHECK=NO
HOMEDRIVE=H:
HOMEPATH=\
HOMESHARE=\\PF1\HOME
ICMHOME=Z:\Software\PTC\INTERC~1
INSTDIR=%CDSROOT%
LOGONSERVER=\\ENGMAHO5
LSF_BINDIR=Z:\Software\LSF\bin
LSF_ENVDIR=\\hwc151\LSF_6.2\etc
MESSAGE=BROADCAST
NUMBER_OF_PROCESSORS=2
OA_PLUGIN_PATH=%CDSROOT%\Share\oaPlugIns
OS=Windows_NT
Path=C:\Program Files\Legato\nsr\bin;Z:\oracle\ora92\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Windows Resource Kits\Tools\;Z:\Software\Perl\5.8.8\bin;C:\Program Files\Oracle\jre\1.3.1\bin;C:\Program Files\Oracle\jre\1.1.8\bin;C:\Program Files\Support Tools\;Z:\Software\LSF\bin;C:\Program Files\PHP\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\EMC RepliStor;C:\GitStack\python;C:\GitStack\python\Scripts;C:\GitStack\git\cmd;Z:\Scripts;Z:\bin;Z:\Cadence\SPB_16.5\tools\bin;Z:\Cadence\SPB_16.5\tools\fet\bin;Z:\Cadence\SPB_16.5\tools\pcb\bin;Z:\Cadence\SPB_16.5\OpenAccess\bin\win32\opt
PATHEXT=.COM;.EXE;.BAT;.PL;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.VBS
PCB_LIBRARY=16
PERL5SHELL=cmd
PHPRC=C:\Program Files\PHP\
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 29 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=1d01
ProgramFiles=C:\Program Files
PROMPT=$P$G
PULLUP_DIFF_PAIRS=TRUE
SESSIONNAME=RDP-Tcp#1
SystemDrive=C:
SystemRoot=C:\WINDOWS
TZ=EST5EDT
VISUALSVN_SERVER=C:\Program Files\VisualSVN Server\
WF_RESOURCES=Z:\oracle\ora92\WF\RES\WFus.RES
windir=C:\WINDOWS

1 个答案:

答案 0 :(得分:9)

原来,这个奇怪的行为被错误定义的原因是PERL5SHELL变量:cmd.exe(Windows中的shell解释器)应该调用一些参数进行正确处理 - 一些更新后参数丢失了。 )

顺便说一句,在The Doc中,它说Perl通常会假设' cmd.exe / x / c'如果根本没有定义PERL5SHELL环境变量,则将其作为shell可执行文件。

P.S。我非常喜欢这个帖子:它清楚地表明了评论的目的。 )