Try running the env command in the script and at your shell prompt. Any variables matching m/^LD_/ are particularly interesting.
Also try which python3 or which python in both contexts. Are they using the same Python installation?
Also try ldd python3 or ldd python in both cases to see what libraries are being loaded. Your error suggests that the httpd is somehow running Python with a different version of the C++ runtime.
It is very suspicious that the error mentions libstc++ under /opt/lampp/lib but a Python module under /usr/local/lib/python3.7.
If you were having a similar issue with Perl, I would ask if you are using mod_perl, but Perl tends to have better backwards compatibility than this.
| [reply] [d/l] [select] |
Thank you very much jcb!
$ENV{LD_LIBRARY_PATH} = '/opt/lampp/lib:/opt/lampp/lib';
was the result when executed via browser and was empty on command line.
I do not really understand what happened but probably LD_LIBRARY_PATH is checked first and is as you said pointing to a non fitting version and stops after failure.
Not sure if the solution is the best but trying
my $ret = `unset LD_LIBRARY_PATH && $command 2&>1`;
did the trick. You made my day, thank you very much again!
| [reply] [d/l] [select] |
Glad to hear it worked out. I just wanted to add that backticks, unless properly used, can very easily introduce security holes, which I wrote about here, where I also show some alternatives. In this case, since you want to also capture STDERR, I might recommend IPC::Run3. You should also be able to unset that environment variable using delete $ENV{LD_LIBRARY_PATH} instead of the unset command, and if you want that change to only be temporary while you run the command, you can use { delete local $ENV{LD_LIBRARY_PATH}; run_command_here }.
use IPC::Run3 'run3';
my @command = ('/path/to/python3.7','/path/to/script.py');
my $ret = do {
delete local $ENV{LD_LIBRARY_PATH};
my $r;
run3 \@command, undef, \$r, \$r or die "run3 failed";
die "command failed, \$?=$?" if $?;
$r };
| [reply] [d/l] [select] |
LD_LIBRARY_PATH specifies directories that the dynamic linker searches first. It is used when testing XS extensions to pick up the newly built extension rather than whatever is installed on the system.
haukex beat me to it, but I recommend simply putting delete $ENV{LD_LIBRARY_PATH} if $ENV{LD_LIBRARY_PATH} =~ m{/lampp/}; somewhere near the top of your script to ensure that any special values your httpd installation is using will not affect your script's subprocesses.
I also strongly advise against using shell commands when they can be avoided, particularly in Perl scripts exposed to the Web. As an example, your solution would have made your program vulnerable to ShellShock, even though you do not actually need a shell anywhere in this application.
How much output does this command produce? You may want to read the output incrementally rather than collecting it all. If so, also look into IPC::Open3 and possibly IO::Pty and Expect.
| [reply] [d/l] |