如果我从自己的主目录su user
获得了bash补全权限,但是如果我su user
从另一个目录没有错误。
Can't locate strict.pm: lib/strict.pm: Permission denied at
/usr/bin/vendor_perl/bash-complete line 7.
BEGIN failed--compilation aborted at /usr/bin/vendor_perl/bash-complete line 7.
至少从90年代后期开始,perl的每个版本都包含引用文件的第7行use strict;
...。
su user
来源/etc/bash.bashrc
,而用户已被.bashrc
吸引。为什么主叫用户在文件系统中的位置会对此进行更改?
有关更多详细信息,请参见my repo,但我想这里已经具备了必要的基础知识。
编辑:有关设置的更多说明。
我在/etc/bash.bashrc中添加了以下几行(发生错误的地方):
if [[ $USER == 'testloginfiles' ]]; then
echo "/etc/bash.bashrc (-: $-) ($(shopt login_shell))"
printf '@INC: %s\n' $(perl -e 'print join ":", @INC')
fi
如果我在主目录中,这是输出:
$ pwd;su testloginfiles
/home/harleypig
Password:
/etc/bash.bashrc (-: himBH) (login_shell off)
@INC: lib:/usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
Can't locate strict.pm: lib/strict.pm: Permission denied at /usr/bin/vendor_perl/bash-complete line 7.
BEGIN failed--compilation aborted at /usr/bin/vendor_perl/bash-complete line 7.
/home/testloginfiles/.bashrc (-: himBH) (login_shell off)
[testloginfiles@sweetums harleypig]$
如果我在另一个目录(例如/tmp
)中,则会得到以下信息:
$ pwd ; su testloginfiles
/tmp
Password:
/etc/bash.bashrc (-: himBH) (login_shell off)
@INC: lib:/usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
/home/testloginfiles/.bashrc (-: himBH) (login_shell off)
[testloginfiles@sweetums tmp]$
有一个@pcronin建议的相对路径,但是我的主目录和/tmp
都没有lib目录。为什么一个会导致错误,而另一个不会呢?
答案 0 :(得分:2)
在Perl中,use strict
告诉perl从名为strict.pm
的文件中查找,加载和导入符号。它通过在@INC
列表中搜索目录的有序列表来完成此操作。有关如何构建的更多信息,请参见this answer。您所看到的错误表明,在成功找到strict.pm
之前,perl在执行用户(可能是testloginfiles)无法访问的路径中进行了搜索。
@INC
的内容可能受运行脚本的目录以及环境变量的影响。在您的情况下,由于问题是在程序从一个目录而不是另一个目录运行时出现的,因此@INC
中的一个(或多个)条目可能是相对路径,例如lib
(而不是/usr/share/perl5
之类的东西),或者可能影响perl的@INC
列表的环境变量在目标用户的环境中是不同的。
运行perl -E 'print join("\n", @INC)';
将产生将搜索的位置列表。在普通用户的外壳程序中运行该脚本,然后将结果与将其添加到testloginfiles的.bashrc
文件中后进行比较。输出差异应解释行为差异。
@INC
中没有任何区别,这使我们了解了两种情况如何以不同的方式解释@INC
。正如您在su
手册页中发现的那样,su
不会更改当前目录,这意味着相对路径完全不会影响@INC
的解释。但是,su
正在更改用户,因此这意味着该用户正在测试/home/harleypig/lib/strict.pm
是否存在。我敢打赌,su用户没有权限读取harleypig的主目录以查看该文件是否存在,从而导致错误。答案 1 :(得分:2)
我没有足够仔细地阅读su
手册页。答案在第一部分:
为了向后兼容,su默认不更改当前 目录并仅设置环境变量HOME和SHELL (如果目标用户不是root用户,则加上USER和LOGNAME)。
因此,我的现有环境包括PERL5LIB=lib
。被留在原地。 /etc/bash.bashrc
可以在我拥有的任何环境中执行。这似乎有安全隐患。
无论如何,以下方法解决了该问题,尽管仍然不能解释为什么它仅从我的主目录给出错误:
$ pwd ; PERL5LIB= su testloginfiles
/home/harleypig
Password:
/etc/bash.bashrc (-: himBH) (login_shell off)
@INC: /usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
/home/testloginfiles/.bashrc (-: himBH) (login_shell off)
[testloginfiles@sweetums harleypig]$