The PERL5LIB environment variable is the only one that is set in the empty environment that launches the perl binary (to find the Sybase::Simple module). And indeed, in an empty environment, the XS .so blob that implements the actual database access layer in Sybase::CTlib (on which Sybase::Simple depends) refers to libraries that can't be resolved (and this is how these Sybase libraries work by design):$ env -i PERL5LIB=.local/lib/perl5 perl -MSybase::Simple Can't load '.local/lib/perl5/x86_64-linux-thread-multi/auto/Sybase/CTl +ib/CTlib.so' for module Sybase::CTlib: libsybct_r64.so: cannot open s +hared object file: No such file or directory at /usr/lib64/perl5/Dyna +Loader.pm line 193. at .local/lib/perl5/Sybase/Simple.pm line 19. Compilation failed in require at .local/lib/perl5/Sybase/Simple.pm lin +e 19. BEGIN failed--compilation aborted at .local/lib/perl5/Sybase/Simple.pm + line 19. Compilation failed in require. BEGIN failed--compilation aborted. $
The code I arrived at from your linked comment to 'steal' the environment from a subshell (with the added requirement of merging with any existing %ENV values), is:$ env -i ldd .local/lib/perl5/x86_64-linux-thread-multi/auto/Sybase/CT +lib/CTlib.so linux-vdso.so.1 (0x00007ffcebdce000) libsybct_r64.so => not found libsybcs_r64.so => not found libsybblk_r64.so => not found libperl.so.5.32 => /lib64/libperl.so.5.32 (0x00007f4970c00000) libc.so.6 => /lib64/libc.so.6 (0x00007f4970800000) libm.so.6 => /lib64/libm.so.6 (0x00007f4970b25000) libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007f4970fc3000) /lib64/ld-linux-x86-64.so.2 (0x00007f4971032000) $
But this still fails (even though the environment is modified correctly (the first line is the content of $ENV{LD_LIBRARY_PATH}):#!/usr/bin/perl BEGIN { my $shellcode = <<__KOEKOEK__; . sybsdk/SYBASE.sh perl -MData::Dumper -e 'print Dumper [\%ENV]' __KOEKOEK__ %ENV = (%ENV => @{eval qx{/bin/sh -c "$shellcode"}}); }; print $ENV{LD_LIBRARY_PATH}; require Sybase::Simple;
If we modify the script to just dump the %ENV hash, we see that all environment variables were indeed set correctly in the parent process from our detour in the qx{} subshell:$ env -i PERL5LIB=.local/lib/perl5 perl ./do_shell_source.pl ~/sybsdk/DataAccess64/ODBC/lib:~/sybsdk/DataAccess/ODBC/lib:~/sybsdk/O +CS-20_0/lib:~/sybsdk/OCS-20_0/lib3p64:~/sybsdk/OCS-20_0/lib3p: Can't load '.local/lib/perl5/x86_64-linux-thread-multi/auto/Sybase/CTl +ib/CTlib.so' for module Sybase::CTlib: libsybct_r64.so: cannot open s +hared object file: No such file or directory at /usr/lib64/perl5/Dyna +Loader.pm line 193. at .local/lib/perl5/Sybase/Simple.pm line 19. Compilation failed in require at .local/lib/perl5/Sybase/Simple.pm lin +e 19. BEGIN failed--compilation aborted at .local/lib/perl5/Sybase/Simple.pm + line 19. Compilation failed in require at ./do_shell_source.pl line 14. $
#!/usr/bin/perl BEGIN { my $shellcode = <<__KOEKOEK__; . sybsdk/SYBASE.sh perl -MData::Dumper -e 'print Dumper [\%ENV]' __KOEKOEK__ %ENV = (%ENV => @{eval qx{/bin/sh -c "$shellcode"}}); }; use DDP; p %ENV;
And this corresponds to what's inside the (Sybase provided) shell script file for their proprietary libraries that is meant to be sourced in the shell's environment:$ env -i PERL5LIB=.local/lib/perl5 perl ./do_shell_source.pl { _ "/usr/bin/perl", INCLUDE "~/sybsdk/OCS-20_0/include:", LD_LIBRARY_PATH "~/sybsdk/DataAccess64/ODBC/lib:~/sybsdk/DataAcc +ess/ODBC/lib:~/sybsdk/OCS-20_0/lib:~/sybsdk/OCS-20_0/lib3p64:~/sybsdk +/OCS-20_0/lib3p:", LIB "~/sybsdk/OCS-20_0/lib:", PATH "~/sybsdk/tools/bin:~/sybsdk/OCS-20_0/bin:/usr/l +ocal/bin:/usr/bin", PERL5LIB ".local/lib/perl5", PWD "/tmp", SAP_JRE8 "~/sybsdk/shared/SAPJRE-8_1_062_64BIT", SAP_JRE8_64 "~/sybsdk/shared/SAPJRE-8_1_062_64BIT", SHLVL 0, SYBASE "~/sybsdk", SYBASE_OCS "OCS-20_0", SYBROOT "~/sybsdk" } $
So, coming back around again: a re-exec is still required in this case (due to the semantics and interaction of LD_LIBRARY_PATH and the system's dynamic linker). Moreover, because a Perl script file is first compiled before it is executed, any statements that fire at compile time (like use) need to be deferred to runtime (using require) when LD_LIBRARY_PATH potentially needs adjustments. Otherwise, the use Sybase::Simple; statements gets triggered before the re-exec through a shell that first sets LD_LIBRARY_PATH, causing compilation to abort due to DynaLoader getting an error from the OS's ld.so when trying to resolve libraries a module's XS .so file is linked to.$ cat sybsdk/SYBASE.sh # # SAP Product Environment variables # SAP_JRE8="~/sybsdk/shared/SAPJRE-8_1_062_64BIT" export SAP_JRE8 SAP_JRE8_64="~/sybsdk/shared/SAPJRE-8_1_062_64BIT" export SAP_JRE8_64 SYBASE_OCS="OCS-20_0" export SYBASE_OCS INCLUDE="~/sybsdk/OCS-20_0/include":$INCLUDE export INCLUDE LIB="~/sybsdk/OCS-20_0/lib":$LIB export LIB PATH="~/sybsdk/OCS-20_0/bin":$PATH export PATH # # Replace lib, lib3p, and lib3p64 with devlib, devlib3p, and devlib3p6 +4 when debugging # LD_LIBRARY_PATH="~/sybsdk/OCS-20_0/lib:~/sybsdk/OCS-20_0/lib3p64:~/syb +sdk/OCS-20_0/lib3p":$LD_LIBRARY_PATH export LD_LIBRARY_PATH SYBASE="~/sybsdk" export SYBASE LD_LIBRARY_PATH="~/sybsdk/DataAccess/ODBC/lib":$LD_LIBRARY_PATH export LD_LIBRARY_PATH LD_LIBRARY_PATH="~/sybsdk/DataAccess64/ODBC/lib":$LD_LIBRARY_PATH export LD_LIBRARY_PATH SYBROOT="~/sybsdk" export SYBROOT PATH="~/sybsdk/tools/bin":$PATH export PATH $
In reply to Re^3: Is require still required?
by uzb-dev
in thread Is require still required?
by Bod
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |