in reply to Re: running a backticks command behaves different in command line and browser
in thread running a backticks command behaves different in command line and browser

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!

Replies are listed 'Best First'.
Re^3: running a backticks command behaves different in command line and browser
by haukex (Archbishop) on Aug 10, 2019 at 11:37 UTC

    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 };
Re^3: running a backticks command behaves different in command line and browser
by jcb (Parson) on Aug 10, 2019 at 21:17 UTC

    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.

      look into IPC::Open3 and possibly IO::Pty

      IMHO those are relatively low-level. Personally, I'd recommend IPC::Run, as it supports interactive communication with the subprocesses it runs and can be used in an Expect-like manner, plus a few other advanced features. I showed one example in the node I linked to.

        Most of the time, I consider "relatively low-level" to be a feature. I have found that the more layers I use, the more likely that something will go wrong somewhere.

        I usually prefer the lowest level at which I can write reasonably concise code. No need to pull in Expect (any of them) if simple pipes are enough. Similarly, if the needs are very simple, no need to pull in Perl when Expect (the Tcl variant) will do.