If I su user
from my home directory I am getting a permission denied for bash-completion, but if I su user
from another directory there is no error.
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.
Line 7 of the referenced file is use strict;
... included with every version of perl since at least the late 90s.
su user
sources /etc/bash.bashrc
and the user being su'd to .bashrc
. Why would the calling user's location in the filesystem change this?
See my repo for more details, but I think I've gotten the necessary basics here.
Edit: More description of the setup.
I've added the following lines to /etc/bash.bashrc (which is where the error is happening):
if [[ $USER == 'testloginfiles' ]]; then
echo "/etc/bash.bashrc (-: $-) ($(shopt login_shell))"
printf '@INC: %s\n' $(perl -e 'print join ":", @INC')
fi
And this is the output if I am in my home directory:
$ 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]$
If I am in another directory (e.g., /tmp
) I get the following:
$ 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]$
There is a relative path as @pcronin suggests, but neither my home directory nor /tmp
have a lib directory. Why is one causing an error and the other is not?
In Perl, use strict
tells perl to go find, load and import symbols from a file named strict.pm
. It does this by searching the ordered list of directories in the @INC
list. See this answer for more information on how that gets built. The error you are seeing indicates that before successfully finding a strict.pm
, perl searched in a path that the executing user (likely testloginfiles) did not have access to.
The contents of @INC
can be affected by both the directory from which the script is run, as well as environment variables. In your case, since the problem manifests itself when the program is run from one directory but not another, it's likely that one (or more) of the entries in @INC
is a relative path, such as lib
(instead of something like /usr/share/perl5
), or, that an environment variable that can affect perl's @INC
list is different in the target user's environment.
Running perl -E 'print join("\n", @INC)';
will produce a list of locations that it will search. Run that in your regular user's shell, and compare the results to what happens if you add it to testloginfiles' .bashrc
file. The difference in output should explain the difference in behavior.
@INC
, which leaves us to understand how the two cases interpreted @INC
differently. As you found in the su
man page, su
isn't changing the current directory, which means that relative paths won't affect the intepretation of @INC
at all. But, su
is changing the user, so it means that the su'd user is testing if /home/harleypig/lib/strict.pm
exists. I'd bet that the su'd user does not have permissions to read into harleypig's home directory to see if that file exists, thus causing the error.