Calling a shellscript from php - not working correctly - php

I am calling a shellscript from php using shell_exec() command. Following is the simple version of the shell script:
args[0] = "tom"
echo "hello"
echo "${args[0]}"
When I run this script from terminal, it gives the following output in terminal:
hello
tom
Whereas when I call this from php using shell_exec() only "hello" is printed and not "tom" . ie; variable assignment is not working when the script is called from php. Why this happens and how can I resolve this.
Any help is appreciated.

Probably PHP executes the script with sh, not Bash; thus arrays (which are a Bash feature) are not supported by the shell.
Workarounds: don't use arrays, or explicitly inboke Bash on the script. (If PHP understands shebangs, having a correct shebang line as the first line of the script may well be sufficient.)

First, args[0] = "tom" should not have space. It should be args[0]="tom"
(I'm not sure is this the problem, but worth to try).
Try this at the end of your code, to see which shell is running your script.
echo "`ps -p $$`"
Try both on terminal and PHP scripts to see if it same shell or not.

Related

export shell environment variable before running command from PHP CLI script

I have a script that uses passthru() to run a command. I need to set some shell environment variables before running this command, otherwise it will fail to find it's libraries.
I've tried the following:
putenv("LD_LIBRARY_PATH=/path/to/lib");
passthru($cmd);
Using putenv() doesn't appear to propagate to the command I'm running. It fails saying it can't find it libraries. When I run export LD_LIBRARY_PATH=/path/to/lib in bash, it works fine.
I also tried the following (in vain):
exec("export LD_LIBRARY_PATH=/path/to/lib");
passthru($cmd);
How can I set a shell variable from PHP, that propagates to child processes of my PHP script?
Am I limited to checking if a variable does not exist in the current environment and asking the user to manually set it?
I'm not 100% familiar with how PHP's exec works, but have you tried: exec("LD_LIBRARY_PATH=/path/to/lib $cmd")
I know that this works in most shells but I'm not sure how PHP doing things.
EDIT: Assuming this is working, to deal with multiple variables just separate them by a space:
exec("VAR1=val1 VAR2=val2 LD_LIBRARY_PATH=/path/to/lib $cmd")
You could just prepend your variable assignments to $cmd.
[ghoti#pc ~]$ cat doit.php
<?php
$cmd='echo "output=$FOO/$BAR"';
$cmd="FOO=bar;BAR=baz;" . $cmd;
print ">> $cmd\n";
passthru($cmd);
[ghoti#pc ~]$ php doit.php
>> FOO=bar;BAR=baz;echo "output=$FOO/$BAR"
output=bar/baz
[ghoti#pc ~]$
A couple things come to mind. One is for $cmd to be a script that includes the environment variable setup before running the actual program.
Another thought is this: I know you can define a variable and run a program on the same line, such as:
DISPLAY=host:0.0 xclock
but I don't know if that work in the context of passthru
https://help.ubuntu.com/community/EnvironmentVariables#Bash.27s_quick_assignment_and_inheritance_trick

Executing SASS script from PHP and getting output

I have this PHP script (test.php):
<?php
$cmd = "/usr/bin/sass --watch file1.scss";
system($cmd);
?>
Now I call my PHP script from CLI this way:
/usr/bin/php test.php
And I get no output (it should print SASS is watching for changes).
If I call the SASS command directly from the shell, it outputs correctly.
Why?
Info: I'm using the PHP 5.3.6 version on OS X Lion
Edit: Please, note that this command watches for changes, it seems to behave differently to a regular command.
Edit2: The command works, it compiles correctly. The only thing lacking is the output (I want to debug and see errors :)
Some command line utilities like sass, manipulate the output pipe in some way that PHP can't use.
So, in this particular case, there is no solution.
system() returns a string. Just echo it.
According to http://se.php.net/system you need to pass in a second argument to system() and the return value of the command will be set in that variable:
<?php
system($command, $return);
echo $return;

Running PHP code/scripts on the command line

I just began learning PHP. I've installed php5 on Linux and wrote very simple code just to get going.
How can I run scripts? I tried using the -f option, but it works as a cat command and just spits out the code to standard output.
The interactive interpreter option works fine. Is a web browser the only way to execute a PHP script?
A simple:
php myScript.php
… should do the job.
If it is acting like cat, then you probably forgot to switch out of template mode and into script mode with <?php
Shorter way for command line:
php -r 'echo "Hello "; echo "Jay";'
OR
php -r 'echo dirname("parent/child/reply") . "\n";'
As already mentioned, you can execute your PHP with the following.
php myScript.php
If you wish to pass an argument(s), you can simply do so like this:
php myScript.php Apples
In your PHP file you can use this argument by accessing the $argv array like this:
<?php
echo 'I like ' . $argv[1];
?>
The above would print our "I like Apples".
Note the array index is 1 and not 0. 0 is used for script name. In this case $argv would be "myScript.php"
For more information, check out my blog post Running PHP from the Command Line - Basics.
Actually, PHP's main purpose is to generate web pages, but there are at least two other options:
command line (CLI) script execution,
interactive shell - which is actually the variant of the previous option,
The first one can be achieved in many ways (eg. by giving proper permissions to the file and calling script by providing its URI, eg. ./index.php), the second one can be invoked by php -a command (as stated in the documentation mentioned above).

Tab autocompletion in bash using php

I'm writing a simple script to autocomplete when I press TAB.
The php script contains a simple "echo".
In this case, the autocomplete works but a "tab" is appended to the output
making it useless
Code from the script
scriptPath='/home/hassen/workspace/scripts/bin/test.php'
_dda()
{
local cur
COMPREPLY=()
unset COMP_WORDS[0] #remove "j" from the array
cur=${COMP_WORDS[*]}
IFS=$'\n\n' read -d '' -a COMPREPLY < <($scriptPath --completion "$cur")
return 0
}
complete -F _dda dda
alias dda=$scriptPath
Code from php script
<?php
echo "hello";
?>
Here is the annoying part:
If I print the echo in Python or Ruby, it works like a charm -- ie each time I press TAB, it calls the scripts and output hello.
Is this a bug with PHP or my code?
They seem to disagree at http://bugs.php.net/bug.php?id=52755
It works as desired here, are you very sure the PHP file itself doesn't hold a tab, possibly after the ?>?
Versions: PHP 5.3.2, GNU bash version 4.1.5
CLIFramework provides a command helps you generate the bash completion script by your command definitions, so you don't have to write the completion script by hands:
https://github.com/c9s/CLIFramework
The screencast:
p.s. it also works for zsh
There is a known problem in PHP that is documented here that prevents this from working.
https://bugs.php.net/bug.php?id=53040
Use /usr/bin/php-cgi instead of /usr/bin/php for running the script and it should work.
I had the same issue, not directly with a custom bash completion, but through Makefile bash completion.
Workaround at Makefile bash autocompletion issue with PHP generated targets

Can't execute PHP script using PHP exec

I am trying to invoke a script which takes several seconds (web services with 3rd party) using the PHP exec call. After much struggling, I reduced this to the classic hello world example. The calling script looks like:
exec('/usr/bin/php /home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &');
When I run this, the output execoutput.txt contains a copy of the invoking script page, not hello world as I expected.
Why can't I get this PHP script to execute using exec? Note that when I change the command to something like ls -l, the output is a directory listing as expected. btw, in case it matters, I did chmod the called script to 755...
Update - I moved the exec call to the end of the calling script and at least now I don't see the calling script executed in the output. Thx to posters and I will try some of these ideas.
Help!
Thanks
Steve
I had this issue also and it turns out this is a bug in php (#11430). The fix is to use php-cli when calling another php script within a php script. So you can still use exec but rather than use php use php-cli when calling it in the browser:
exec("php-cli somescript.php");
This worked for me.
What exec is doing is taking the rightmost command and appending it to your destination. If you have the shebang line in your php script, you shouldn't need to include the binary directive of the php interpreter.
if you just want the script's output, try:
exec('/home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &')
however if you do not want the errors to be in the file, you should redirect the STDERR prior to outputting to the file. Like so:
exec('/home/quote2bi/tmp/helloworld.php 2> /dev/null > /tmp/execoutput.txt')
the above should only output the "Hello World" to the execoutput.
Edit:
Interesting you are getting this behaviour. You stated the command "ls" worked. Try making an alias for this and forward it to a file like so:
alias pexec='php /home/quote2bi/tmp/helloworld.php'
then
exec('pexec > /tmp/execoutput.txt 2>&1 &')
it seems to be a problem with the way exec handles input as opposed to the shell itself.
-John
The problem is with PHP itself, it treats everything as $argv in the script. It doesn´t redirect the output to a file ou to /dev/null.
I faced the same problem some time ago. What I did is to create a runscript.php in /opt/php-bin and then inside this script run what It should be running. Something like this:
$script = $argv[1]
$params = implode(' ', array_slice($argv, 2));
$cmd = "{$script} {$params} > /dev/null &";
$output = array();
$return = 0;
exec("php {$cmd}", $output, $return);
exit((int)$return);
And then you call it using:
exec('/opt/php-bin/runscript.php /path/to/your/script.php arg1 arg2')
It´s the only way I managed to get this working.
To avoid the stated problems of PHP in this area, why not put this in inside a shell script? PHP can then execute the shell script which has all the redirections handled internally.
If you need to dynamically change things, then why not write the shell script and then execute it (and of course, clean up afterwards)?
if you are just simply running a php script one possible way to execute the entire code is to use the include() that will run the php file and output any results. You cannot direct the output to a text file but it should appear in the browser window if you're Hello World php script looks like
<?php echo "Hello World!"; ?>
then it will spit that out in the browser. So your second code would look like
<?php include("helloWorld.php"); echo " PHP ROCKS";?>
resulting in a page that would look like,
Hello world! PHP ROCKS
This runs as if you run the script from browser.
This came across while working on a project on linux platform.
exec('wget http://<url to the php script>)
Hope this helps!!

Categories