首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Scalar::Util运行perl脚本失败,因为“尝试重新加载Scalar/Util.pm失败”。

使用Scalar::Util运行perl脚本失败,因为“尝试重新加载Scalar/Util.pm失败”。
EN

Stack Overflow用户
提问于 2022-09-04 21:45:55
回答 1查看 174关注 0票数 0

我最近切换到Mac M1 (从Ubuntu),并安装了Perl从自制。

我已经安装了一些我通常使用的perl包,没有任何问题。不幸的是,在运行时,任何依赖于(或使用依赖于) Scalar::Util或List::Util的perl程序都会失败,错误如下:

代码语言:javascript
复制
Attempt to reload Scalar/Util.pm aborted.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/YAML.pm line 21.
BEGIN failed--compilation aborted at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/YAML.pm line 21.
...

代码语言:javascript
复制
Can't load '/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace (_Perl_croak_memory_wrap) at /System/Library/Perl/5.30/XSLoader.pm line 96.
 at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/List/Util.pm line 24.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/Scalar/Util.pm line 23.

我也尝试过安装perlbrew作为替代,但在那里没有成功。我还检查了PERL5LIB路径中的所有内容是否正确。

使用List::Util,我成功地从CPAN安装了一个较新的版本,但仍然得到了相同的错误。( builtin Scalar::Util是最新版本)

任何关于如何让它们发挥作用的建议,我担心这是一个M1问题,但我不确定这可能是xcode问题。

您可以通过以下方式复制:

代码语言:javascript
复制
$ cpanm VCSL::Which
$ vcsvimdiff -v
Can't load '/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace (_Perl_croak_memory_wrap) at /System/Library/Perl/5.30/XSLoader.pm line 96.
 at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/List/Util.pm line 24.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/bin/vcsvimdiff line 12.
BEGIN failed--compilation aborted at /opt/homebrew/Cellar/perl/5.34.0/bin/vcsvimdiff line 12.

不幸的是

代码语言:javascript
复制
perl -MScalar::Util -e 1
or
perl -MList::Util -e 1

两人都成功地跑了。我查看了我的PERL5LIB路径,只看到了本地的perl路径。

代码语言:javascript
复制
$ perl -E 'say join "\n", split /:/, $ENV{PERL5LIB}'

/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0

如果没有系统perl引用,这一切看起来都很好。

EN

回答 1

Stack Overflow用户

发布于 2022-09-05 08:51:56

摘要:

  • 检查一下你没有遗漏什么
  • 检查perl -V,查看它是哪一个perl及其默认模块搜索路径
  • 检查环境变量(如PERL5LIB )中的冲突值。
  • 查看正在运行的程序的shebang行。

你什么都带了吗?

正如H kon所指出的,似乎有两个perl安装相互干扰。但是,正如池加米所说的,“从未见过”错误信息。我也没有,但是StackOverflow已经看到了

perldiag中的条目是,程序试图加载模块,第一次失败,然后再次尝试:

代码语言:javascript
复制
Attempt to reload %s aborted.
        (F) You tried to load a file with "use" or "require" that failed to
        compile once already. Perl will not try to compile this file again
        unless you delete its entry from %INC. See "require" in perlfunc and
        "%INC" in perlvar.

我不知道是什么让它第一次失败,但是您应该用一些简单的方法检查一下,看看是否可以加载模块:

代码语言:javascript
复制
 $ perl -MScalar::Util -e 1

但实际上,这比这更棘手。也许那个perl可以加载它,但是其他一些perl无法加载它。而且,也许您有多个Scalar::Util的安装,但是特定的perl、环境和程序设置合谋选择了错误的一个。

环境可以告诉perl在哪里查看。

但是,也许所有这些都行不通。

首先,找出您想要使用的perl,并检查其设置:

代码语言:javascript
复制
 $ perl -V

在输出的末尾,您应该会看到有趣的环境设置和默认的模块搜索路径。对于干净的会话,我没有任何包含PERL的环境变量

代码语言:javascript
复制
  %ENV:
  @INC:
    /usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0/darwin-2level
    /usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0
    /usr/local/perls/perl-5.36.0/lib/5.36.0/darwin-2level
    /usr/local/perls/perl-5.36.0/lib/5.36.0

然而,我可以污染我的环境。我将设置一个PERL5LIB值,它将为默认模块搜索路径添加目录:

代码语言:javascript
复制
 $ export PERL5LIB=/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level:/usr/local/perls/perl-5.10.1/lib/5.10.1:/usr/local/perls/perl-5.10.1/lib/site_perl/5.10.1/darwin-2level:/usr/local/perls/perl-5.10.1/lib/site_perl/5.10.1

再次检查perl -V,就会发生以下有趣的事情:

代码语言:javascript
复制
Perl lib version (5.10.1) doesn't match executable version (v5.36.0) at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/Config.pm line 50.
Compilation failed in require.
BEGIN failed--compilation aborted.

如果我尝试用-M从命令行加载-M,如果您混淆了perls,这就是我所期望的:

代码语言:javascript
复制
$ perl -MScalar::Util -e 1
Can't load '/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace '_PL_sv_no' at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/XSLoader.pm line 73.
 at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/List/Util.pm line 23
Compilation failed in require at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/Scalar/Util.pm line 23.
Compilation failed in require.
BEGIN failed--compilation aborted.

程序可能不正确地调整@INC

我不认为这是cpanm的问题,因为现在全世界都会抱怨的。但是,如果某个程序正在使用@INC做一些奇怪的事情,那么它可能添加了错误的内容。

我认为这可能是他们使用的一组供应商模块目录,其中一些模块是针对特定的perl的。当您使用不同的perl时,就会得到二进制不匹配的情况。

程序选择他们的解释器

https://stackoverflow.com/q/59809285/2766176注意到他们家酿的cpanm是用perl系统硬编码的。

但是还有另外一部分涉及到。您正在运行一些程序,而这些程序选择perl。如果您查看它们的第一行,它们要么有通向perl的绝对路径,如下所示:

代码语言:javascript
复制
 #!/usr/bin/perl

或者他们玩了一个把戏,在您的PATH中找到第一个perl。

代码语言:javascript
复制
 #!/usr/bin/env perl

我不喜欢第二个,因为我不确定它会首先找到哪一个perl。在掌握Perl中,我有一个很长的例子,有人调用了一个程序" perl ",将它放在PATH中的一个用户控制的目录中(或者为您添加到PATH中),然后就像它真正的perl一样,但在执行过程中关闭了污染检查。也许不是你的问题,但当你让程序猜谁将处理它,奇怪的事情可能会发生。

例如,我想我还没有为5.36.0版本安装cpanm:

代码语言:javascript
复制
$ head -1 `which cpanm`
#!/usr/local/perls/perl-5.34.1/bin/perl

当我只运行cpanm时,它将使用v5.34.1和我为此设置的任何设置。

我可以直接告诉它要使用哪个perl,但是我需要告诉那个perl在哪里可以找到该程序:

代码语言:javascript
复制
$ perl5.36.0 `which cpanm` ...

同样,我有一些程序的旧版本,我用我打算使用的版本来解决(我做了很多针对许多很多perls的操作):

代码语言:javascript
复制
$ head -1 `which cpan5.10.1`
#!/usr/local/perls/perl-5.10.1/bin/perl


$ head -1 `which cpan5.12.5`
#!/usr/local/perls/perl-5.12.5/bin/perl

当您安装程序(如cpanm )时,安装将调整安装它的perl的shebang行。简单地运行cpanm并不意味着您正在安装到您认为是的perl中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73603018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档