【问题标题】:What could cause Perl system calls to start failing?什么可能导致 Perl 系统调用开始失败?
【发布时间】:2012-06-18 13:59:38
【问题描述】:

一个小要求:我每天阅读 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

【问题讨论】:

  • 也许这个问题更适合 ServerFault 或 SuperUser?
  • 有人在服务器上安装了 Cygwin 吗?请发布环境的副本(您可以清理敏感变量 values 但确保所有变量的名称都在那里)。 COMSPEC 中有什么内容?
  • 当您删除 PERL5SHELL 环境变量时会发生什么?不应该是PERL5SHELL=cmd /x /c之类的吗?
  • Re “在这种情况下,Perl 将正斜杠 (/) 切换为 DOS/Windows 反斜杠 (),它多年来一直做得很好。”,Perl 从未切换过任何 @ 987654327@ 到 \ .
  • Windows 内部可以很好地处理正斜杠; perl 实际上并没有转换任何东西。

标签: windows perl


【解决方案1】:

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

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

附:我真的很喜欢这个线程:它清楚地显示了 cmets 的用途。 )

【讨论】:

  • 再次感谢您的帮助!我只定义了那个 var 因为一个新的 Perl 脚本(foswiki)抱怨它没有定义。我希望我知道它会造成这么多麻烦......
  • +1 我很高兴它与定义 shell 的环境变量有关。
  • 谢谢你,顺便说一句,你也应该受到赞扬:你首先提到环境可能是问题的根源。
猜你喜欢
  • 2022-06-15
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 2012-05-12
  • 2011-11-11
  • 2020-06-16
相关资源
最近更新 更多