12

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

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

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

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

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

那应该打印一个“目录”列表,但它会打开一个子外壳。如果我输入“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”解释为回车(我认为)并寻找剩余的“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
4

1 回答 1

10

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

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

PS我真的很喜欢这个帖子:它清楚地表明了评论的目的。)

于 2012-06-18T18:30:01.373 回答