I'm trying to launch a perl script from within a PHP-based website. In that perl script, I'm using a package, that's installed on a non-standard location. So, to make all packages on that location available without launching perl as "perl -I /path/to/packages", or placing "lib /path/to/packages;" in every perl script I make, I added "/path/to/packages" to the PERL5LIB environmental system variable, and everything works fine when a regular user executes the script. However, when this perl-script is launched from the website, all environmental system variables seem to be inaccessible (tested with $ENV{"PERL5LIB"} and $ENV{"LOGNAME"} in perl, both are uninitialized), causing the perl script to crash because it can't find the required packages in #INC.
How can I make those perl packages available for launch from the website without lauching every perl script with "perl -I /path/to/packages script.pl" and without putting "lib /path/to/packages;" on top of every perl script?
There is two possible way to solve it:
If you own/access the web server, you could add variables globally.
(for apache)
http://www.perlmonks.org/?node_id=844715
<Directory /var/www/>
SetEnv PERL5LIB /your/lib/path
Another workaround that you could setup and maintain your libraries related to script then reach it from your perl script. Please check out FindBin module for this. http://www.perl.com/pub/2002/05/14/mod_perl.html
You could store your script ./bin/, and your libs at ./lib/
If you are using your libs more than one place, you could link it to ./lib/.
#!/usr/bin/perl
use FindBin ();
use lib "$FindBin::Bin../lib/";
use test;
print "test.pm => $INC{'test.pm'}\n";
You have to insure that PER5LIB is set in the environment that your web server launches from.
You'll need to consult the manual for your particular web server to find the configuration command that set environment variables, or you'll need to modify the launcher script (e.g. apachectl) an add the logic to properly set PERL5LIB.
aaaaannnd... somebody was posting examples at the same time I was posting this...
I asked the system admin for help and found out that we're not using apache (as expected) but nginx. That being said, the solution was to add the PERL5LIB definition to the /etc/nginx/fastcgi_params file like this:
sudo echo 'fastcgi_param PERL5LIB "custom/path/to/perl/modules";' >> /etc/nginx/fastcgi_params
sudo service nginx reload
Thank you #LenJaffe and #user1126070 for pointing me in the right direction!
Related
I need to run a php script to refresh data every 10 minutes, and I'm doing it using cron.
crontab -e configuration is:
*/10 * * * * php my_file.php
In this file, I'm using $_SERVER['my_env_var'] to retrieve the value of the variable, which is an encrypted string (it is set in apache2.conf as SetEnv MY_ENCRYPTED_VALUE something).
Using debug in web browser will correctly output the values (it is being run with apache, so it can read the file and recognize I'm calling the variables set on the server).
However, cron is using the CLI. And when using
<?php
print_r($_SERVER);
?>
my variables are not listed in here.
I do understand they do not share the same .ini files and SAPIs (apache2handler vs cli).
I have seen other posts that say:
"Set them as /etc/environment variables"
but if possible I would prefer not to use that (is it secure?).
But, is there a way to access Apache2's SetEnv variables through PHP CLI?
As #CBroe said, cli has no relationship with PHP in cli mode. And you still need some common environment variable, you can take help from CI CD pipelines. It will keep those secure and at one place.
We are talking about almost same thing, i am saying that env should be written by the pipeline to target system, rather manually maintained by some individual team.
CI CD pipeline give us a way to use env variables for any reason and security is very good candidate to use that.
I am using PHP in an HTML5 document in Windows 10, calling shell_exec() which I want to use to call Rscript, ultimately. The problem I have run into is that the environmental %PATH% variable in Windows that shell_exec() is getting from some cache somewhere is yesterday's version, which doesn't include the path to Rscript, so the call fails.
I carefully set both the personal and the system environmental PATH variables in Windows using the Windows tool to include a path to Rscript, and then later to remove another link to PERL to make sure the total path was below 260 characters, then I moved the Rscript path up to the front. No joy.
The following command pulls up a %PATH% from somewhere but I have no idea where If I simply use CMD to go to that directory and issue the commands via that shell, they find the right path, but if I call it via shell_exec() it's the old path. I've tried rebooting and clearing the browser caches so I'm pretty sure this is a PHP cache thing, but I see many references to cahces here to figure out which one I'm facing.
So any help would be appreciated.
This code shows the OLD path, not the current one:
shell_exec("echo %PATH% > outputFilexx.Rout 2> errorFilexx.Rout");
Environment variables are not really cached but simply part of the run-time environment of a process. A new process inherits all environment variables and their values - at that time when it is started - from its parent process.
After that changing the value of an environment variable in one process does not affect other (already running) processes.
How to change an environment variable of a running process depends on the program and may not always be possible. To "reload" environment variables otherwise you need to restart the process - and possibly also their parent processes since otherwise they would inherit the "old" values from them again.
I.e. you not only should restart PHP/Apache but also the WAMP console so %PATH% is inherited from the system environment. To be completely sure you can just reboot the whole machine.
But environment variables may also be change via application depend configurations. So you could change the PATH only for
Apache via SetEnv
PHP via putenv()
I had developped a shell script and I wanted to create an UI with it. I decided to use a web interface with a local server because I have few knowledges in HTML/PHP, more than QT or Java. I simply want that my html can run a shell script on my computer.
I have an Apache php server which I start in localhost with apachectl.
In /var/www/html/ I have a shell script and a test_web.php file which execute this script with exec('/var/www/html/test.sh')
In my html I have this:
<form method="POST" action="test_web.php?">
<input type="submit" value="Execute" name="exec">
</form>
If I click on Execute, it opens a new page where I see the output of echo commands from the script but it is not executed on the terminal as a standard script (like if the script is not executed on server side).
I want this script to be executed as started from the terminal.
Thank you for your help
As suggested by some commentators, you could use the Apache cgi features to be able to execute directly your test.sh file (1), but since you say you are using a Php enabled Apache server, you have an alternative and easier option with Php which you partially already tried (2). In both cases, you will need to take care of the permissions and ownership of the bash script, and its execution environment for it to produce the same results as on the command line (3).
1. CGI
CGI stands for Common Gateway Interface. It allows web servers to execute programs that are executable on the host, and interface with the web server. That is a protocol per se, and CGI can be used not only to execute programs, but also for creating dynamic sites. You could program a dynamic website in any language, provided the executable is programmed to receive data via stdin from the server and interpret the headers, decode any contents properly, and that the program can return proper dynamic data to the server via stdout, with proper headers, Content-type, etc.
There are libraries for helping in this task for many languages (for C, Perl has a CGI module in is Core Modules, etc., and even for Bash).
On Linux, to use CGI with Apache 2, you would need to make sure that your Apache configuration loads the required module for supporting it, and select the directory where your web server will be allowed to execute the programs:
# uncomment or add the directive for the module
LoadModule cgid_module modules/mod_cgid.so
# one way to allow the server to execute cgi programs is to
# set a ScriptAlias directive to a directory dedicated to CGI programs
ScriptAlias "/cgi-bin/" "/var/www/html/cgi-bin/"
You put your test.sh script in /var/www/html/cgi-bin/, and browser can be pointed to http://localhost/cgi-bin/test.sh to directly execute the script. There are other configurations possible, see this Apache CGI tuturial.
If you need to execute the Bash program and want your CGI to send anything to the browser, the first echo sent by the Bash script shall be the following output:
Content-type: text/html
followed by whatever dynamic html you want to produce.
2. Php
Really all these complications may not be necessary since you say you use a Php enabled Apache server, and since you probably do not want the Bash script to send html directly to the browser.
In that case, the shell_exec() command or backticks operator, will allow you to run your Bash script and obtain its output in a Php variable, and do whatever you want to do with it in Php.
You say you have tried using the exec command, which should work also, except that you get a status code in response, and not the program output.
If your execution command does not work at all, this may be because of permissions, ownership or execution environment issues.
3. Permissions, ownership and execution environment
Have a look at your Apache logs for errors produced by the exec or shell_exec commands.
The script needs to have execution permissions, and needs to be readable and executable by the web server.
For instance, on Debian, Apache web server runs as a user www-data, so a script would need to be owned and executable by that user:
chown www-data:www-data test.sh
chmod u+x test.sh
You can find the location of the Apache logs and the user and group under which the web server runs in your Apache configuration file by inspecting (as root) the results of:
apachectl -S
Another possible issue is the environment in which Apache will be running the script. That environment, may or not include the same environment variables, the $PATH will be different and may not include all directories available to a "normal" user executing the same script on the console.
Again, check for errors in the logs.
The most frequent cause for failure is a Bash command not found because it is not in the $PATH of the Apache process. The quick fix is then to change the script to prefix the command with its full path.
So, for instance, if your test.sh uses a program called validjson, open your terminal as a user that can execute the script without errors, and check where it is:
$ which validjson
validjson: /usr/local/bin/validjson
and instead of calling validjson in the script assuming it is in the $PATH, call it instead with its full path /usr/local/bin/validjson reported by the which command.
If you are calling other scripts or programs, they may have the same issues, check that until you have debugged the execution of your script.
So I'm writing a web server (I know, like the world needs another one!) And I want to call php through CGI. I've got a nice working CGI1.1 implementation good enough to run perl cgi scripts for example.
Now I want to run php. But when my cgi module calls the php program it returns a 404.
How do I get this working?
The details:
I'm running on ubuntu with php5. In my web server, I pass cgi requests to a handler that will find the program and call it with the sc ript as an argument. So here is the code that spawns the cgi process:
chdir( dir );
execve( argv[0], argv.data(), (char* const*) req.posixEnv() );
The command I'm running is equivalent to:
/usr/bin/php5-cgi /home/rafael/webserver/data/cgi-bin/test.php
This means I've set "dir" to:
/home/rafael/webserver/data/cgi-bin
And the cgi process should run in that directory. Argv[0] is "/usr/bin/php5-cgi", argv.data() returns a null terminated array with the following elements:
/usr/bin/php5-cgi
/home/rafael/webserver/data/cgi-bin/test.php
NULL
The process environment contains the CGI environment that includes a block of the usual CGI environment variables.
When I run the above command from a shell, that is by literally typing it into a shell, the script runs fine and php generates the test page. When I call it from CGI it returns:
Status: 404 Not Found
X-Powered-By: PHP/5.3.10-1ubuntu3.2
Content-type: text/html
No input file specified.
Now I know more or less what is happening. PHP is detecting if it is running in CLI or CGI mode, and searching for the script to run differently in each mode. In CGI mode it is probably using CGI environment variables like SCRIPT_FILENAME and DOCUMENT_ROOT to resolve the script name. I've tried a whole bunch of things - different settings for these variables. But none of it works.
What I do know: The whole spawning of PHP, and reading output works. For example if I remove certain CGI variables such that it thinks it is running in CLI mode it works great - generates the page and everything.
What I need to know is:
what is the right way to set up the CGI environment variables for the php-cgi to find my script.
what is the right way to call a php script from exec. I'm using full paths for everything as an effort to debug this. I'd prefer to use relative paths.
All the documentation I can find is about configuring php for cgi on particular web servers. I need to know this from the perspective of someone writing a server.
#EDIT: I have a simpler example that eliminates c++. I'm pretty sure that part is working correctly anyway. Say I make a script that calls php-cgi, and I try to emulate the cgi calling conventions in a shell.
This works:
#export GATEWAY_INTERFACE="CGI/1.1"
export REDIRECT_STATUS=200
export SERVER_PROTOCOL="HTTP/1.1"
export DOCUMENT_ROOT="/home/rafael/web"
#export SCRIPT_FILENAME="cgi-bin/test.php"
export SCRIPT_NAME="cgi-bin/test.php"
/usr/bin/php5-cgi test.php
But this doesn't:
export GATEWAY_INTERFACE="CGI/1.1"
export REDIRECT_STATUS=200
export SERVER_PROTOCOL="HTTP/1.1"
export DOCUMENT_ROOT="/home/rafael/web"
#export SCRIPT_FILENAME="cgi-bin/test.php"
export SCRIPT_NAME="cgi-bin/test.php"
/usr/bin/php5-cgi test.php
I think probably some combination of DOCUMENT_ROOT, SCRIPT_FILENAME and SCRIPT_NAME should work.
The thing that was messing it up was the setting of "doc_root" in php.ini. I unset that like so:
doc_root =
And now cgi environment variables work much more like the CGI spec says. Eg. The following thing now works:
export GATEWAY_INTERFACE="CGI/1.1"
export SERVER_PROTOCOL="HTTP/1.1"
export SCRIPT_FILENAME="/home/rafael/web/cgi-bin/test.php"
export SCRIPT_NAME="test.php"
export REDIRECT_STATUS="200"
/usr/bin/php5-cgi test.php
I have access to a shared web host.
The website installed there uses exec(). About 4 months ago the function was enabled, but now they have put it on the disable_functions list. They put exec, passthru and shell_exec on that list but they forgot to put system:) This makes me think that the server admin is not very aware on what he's doing. Anyway, they now say that those functions should have never be enabled and they wont re-enable them.
The installed website uses exec() to start some php scripts that would do some background work. Right now i'm looking to see if there is any other "legal" way to start those php scripts in background(i expect system() to work, but maybe they will disable it in the future also).
And now my simple question:
In the perdefined file structure i see a cgi-bin folder. Whats its use? From what i read on the web it is used to generate "dynamic" pages when accessed through the browser, but the server has php anyway installed, so i dont see its use.
/cgi-bin/ is a directory where CGI script should be placed.
You can work around restrictions on exec in PHP by using CGI.
Create a file named somefile.sh with contents:
#!/bin/sh
printf "Content-Type: text/plain\n\n"
#your code here
This will only work if /bin/sh actually exists, and is executable (if you're not in a chroot without /bin/sh for example)
There are enough ways to get a command executed. If they disable CGI, you can continue with SSI.