How to add shebang #! with php script on linux? - php

I'm having a little issue with adding shebang #! with my php script on RedHat linux. I have a small piece of test code with shebang added (I've tried different variations as well), but I get the following error message everytime I try to run the script.
Error msg:
-bash: script.php: command not found
Test script:
#!/bin/env php
<?php echo "test"; ?>
Shebang #! variations:
#!/usr/bin/php
#!/usr/bin/env php

It should (for most systems) be #!/usr/bin/env php, but your error isn't related to that.
-bash: script.php: command not found
It says that script.php is not found.
If the problem was the shebang line then the error would say something like:
bash: script.php: /usr/env: bad interpreter: No such file or directory
Presumably, you are typing script.php and the file is not in a directory on your $PATH or is not executable.
Make it executable: chmod +x script.php.
Type the path to it instead of just the filename, if it is in the current directory then: ./script.php.
Instead of 2, you can move/copy/symlink the file to somewhere listed in $PATH or modify the $PATH to include the directory containing the script.

If you script is not located in your /usr/local/bin and is executable, you have to prefix calling your script with php like this:
php myscrip.php
For shebangs, here is what I use:
Like this:
#!/usr/bin/php
or this:
#!/usr/bin/env php

In reply to #NVRM's comment regarding only single use of -d, this is not true.
Start with a chmod +x script as
#!/usr/bin/php
<?php
phpinfo();
and run script | grep -E 'memory_limit|error_reporting', and you'll see
error_reporting => no value => no value
memory_limit => 128M => 128M
Now add some -d entries so you have
#!/usr/bin/php -d memory_limit=2G -d error_reporting=-1
<?php
phpinfo();
and re-run script | grep -E 'memory_limit|error_reporting', and you'll now see
error_reporting => -1 => -1
memory_limit => 2G => 2G
Thus demonstrating you can set multiple options.
In fact, the entire command line is what you are working with here. So you can load extensions, use a different config, etc., everything you can do at the command line.

Leaving here some little notes:
To use a php binary located inside the same folder.
As example a php7.2 executable copied from /usr/bin is in the same path along a hello script.
#!./php7.2
<?php
echo "Hello!";
To run it:
./hello
Which behave just as equal as:
./php7.2 hello
This give portability, but beware of system architectures, the php binary might not match the target platform.
Setting allowed memory from the hashbang:
We can set one INI entry from the hashbang line:
#!/usr/bin/php -d memory_limit=2048M
<?php
phpinfo();
exit;
Then to see if php had understood, using phpinfo():
./myphpProg | grep memory
Correct shell output should contain:
memory_limit => 2048M => 2048M
Doing the above is similar as this command line:
php -d memory_limit=2048M myphpProg.**php**
This is why we can set only one ini value in hashbangs, as php accept only one -d parameter at a time.

find callable shebang for PHP in Linux,
Don't memorize this it, learn how to use it
which php
output
zeus#pop-os:~$ which php
/usr/bin/php
then shebang must be
#!/usr/bin/php

Related

Running PhantomJS from PHP with exec()

I've got the following script:
#!/bin/sh
export DISPLAY=:0
phantomjs --version
It try to run it from the following PHP script:
<?php
$result = shell_exec('sh test.sh');
echo $result;
?>
This script return the following error:
[Thu Jun 19 10:31:31 2014] [error] [client] test.sh: line 3: phantomjs: command not found
I tried to run phantomjs -v by hand in a console, and it runs fine. I checked the PATH, and phantomjs is correctly defined and found.
The execution environment is a virtual Server with LiveConfig.
Can someone help me understand what I'm doing wrong ?
It could be an issue with shell_exec() and line breaks,
try adding "2>&1" to the string you are passing:
$result = shell_exec('sh test.sh 2>&1');
this worked for me, found it in the top comment here, naturally ;)
Your PATH probably lacks the location for the phantomjs executable. PhantomJS is probably installed in /usr/local/bin so you need to add this to your PATH variable:
#!/bin/sh
export DISPLAY=:0
PATH=$PATH:/usr/local/bin
phantomjs --version
To check what the current PATH is, you could begin the shell script with:
#!/bin/sh
echo $PATH
<?php
exec('/usr/local/bin/phantomjs path/somescript.js');
?>
Yes. Sometimes phantomjs don't need full path in some environment without generate any error. However, sometimes it does.
Always use the full path for all argument in the php command.
Did you use the fullpath for hello.js?
Do not use exec(). Never. It's a bad way.
Use the php-phantomjs and PhantomJS Runner instead.

Running php script (php function) in linux bash

How we run php script using Linux bash?
php file test.php
test.php contains:
<?php echo "hello\n" ?>
From the command line, enter this:
php -f filename.php
Make sure that filename.php both includes and executes the function you want to test. Anything you echo out will appear in the console, including errors.
Be wary that often the php.ini for Apache PHP is different from CLI PHP (command line interface).
Reference: https://secure.php.net/manual/en/features.commandline.usage.php
First of all check to see if your PHP installation supports CLI. Type: php -v. You can execute PHP from the command line in 2 ways:
php yourfile.php
php -r 'print("Hello world");'
There are two ways you can do this. One is the one already mentioned, i.e.:
php -f filename.php
The second option is making the script executable (chmod +x filename.php) and adding the following line to the top of your .php file:
#!/path/to/php
I'm not sure though if a webserver likes this, so if you also want to use the .php file in a website, that might not be the best idea. Still, if you're just writing some kind of script, it is easier to type ./path/to/phpfile.php than having to type php -f /path/to/phpfile.php every time.
Simply this should do:
php test.php
just run in linux terminal to get phpinfo .
php -r 'phpinfo();'
and to run file like index.php
php -f index.php
php -f test.php
See the manual for full details of running PHP from the command line
php test.php
should do it, or
php -f test.php
to be explicit.
I was in need to decode URL in a Bash script. So I decide to use PHP in this way:
$ cat url-decode.sh
#!/bin/bash
URL='url=https%3a%2f%2f1%2fecp%2f'
/usr/bin/php -r '$arg1 = $argv[1];echo rawurldecode($arg1);' "$URL"
Sample output:
$ ./url-decode.sh
url=https://1/ecp/

Custom php.ini when using #!/usr/bin/php

I have a script in which I am trying to load a custom php.ini file. The script is run on *nix systems via a #!/usr/bin/php -qc /path/to/php.ini header. When doing this, however, PHP reports that the loaded php.ini file does not exist, i.e. none is loaded.
If I execute php -qc /path/to/php.ini /path/to/script in the command line directly, it picks up the php.ini -- is it possible to override the php.ini file using the #! notation?
PHP does not like parsing arguments from the shebang. It only allows one to be present. You can however trick it by omitting the space for the first argument parameter:
#!/usr/bin/php -qc/etc/php5/my.ini
(Obviously this method only works for one such parameter with concatenated argument.)
You can workaround this shebang portability specification fail by wrapping your PHP script in a Shell script:
#!/bin/sh
SCRIPT_PATH="$(dirname $0)"
/usr/bin/env php -qc /path/to/php.ini -f $SCRIPT_PATH/my_original_script.php

PHP system() - return status is always 0

I need to get the following scripts running.
// File: script_a.php
<?php exit(1); ?>
// File: script_b.php
<?php
system('php script_a.php', $return);
var_dump($return);
?>
Now my problem: On my windows system running script_b.php shows int(1) as expected. On our Unix-Server I always get int(0), what makes it impossible for me to check, if a certain failure happens inside the script_a.php.
Does anybody knows this problem and how to solve it?
You might want to check if it's calling the right php executable on th Unix machine. On many UNIX systems you would need to call the php-cli executable insted of the php one for use on the command line.
Another thing to check would be permissions. Maybe the user executing the script_b.php script doesn't have permissions to execute script_a?
__halt_compiler() is called somewhere , able to check that ?
Try making the PHP system call with the absolute path of both the PHP executable and the script filename, e.g.: system('/usr/bin/php /path/to/script_a.php', $return);. Maybe it's a path issue. (You may find the absolute path of your PHP executable with: which php).
Also, as someone suggested, try debugging the actual return value of script_a.php on your UNIX server by running php script_a.php; echo $? on the command line. That echo will output the last return value, i.e., the value returned by script_a.php.
Anyway, I suggest doing an include with a return statement as described in Example #5 of the include() documentation. If you can adapt your scripts like this, it's a more efficient way of communicating them.
// File: script_a.php
<?php return 1; ?>
// File: script_b.php
<?php
$return = (include 'script_a.php');
var_dump($return);
?>
Have you checked if safe_mode is enabled on unix server?
PHP Note:
Note: When safe mode is enabled, you
can only execute files within the
safe_mode_exec_dir. For practical
reasons, it is currently not allowed
to have .. components in the path to
the executable.
Or maybe the system function is forbidden to be executed?
I can't reproduce it either (PHP 5.3.3, Ubuntu).
When I set the exit-value to something better grep-able, like "666", tracing the scripts returned also what is expected:
strace -f php5 script_b.php 2>&1 | grep EXITSTATUS
[pid 18574] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0, NULL) = 18575
waitpid(18574, [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0) = 18574
The "-f" to strace let's it follow child processes as you use the system call. "2>&1" redirects stderr to stdout to let everything grep. You can also pipe it to "|less" to go through but the output is long and not very readable.
I can't reproduce this on my system, Ubuntu Hardy. Here's a sample:
/tmp$ mkdir /tmp/sbuzz
/tmp$ cd /tmp/sbuzz
/tmp/sbuzz$ echo '<?php exit(1); ?>' >script_a.php
/tmp/sbuzz$ cat >script_b.php
<?php
system('php script_a.php', $return);
var_dump($return);
?>
/tmp/sbuzz$ php script_b.php
int(1)
/tmp/sbuzz$ echo '<?php exit(2); ?>' >script_a.php
/tmp/sbuzz$ php script_b.php
int(2)
/tmp/sbuzz$
Exit code 0 means successful execution of the program, so it kind of sounds like you are perhaps running the wrong script_a.php or perhaps the "php" executable isn't doing what you are expecting? Perhaps you have a script called "php" that is in your path before the interpreter? What does "which php" report? On my system it says "/usr/bin/php".
If PHP can't find the script, it would exit with 1, for example:
/tmp/sbuzz$ cat script_b.php
<?php
system('php doesnt_exist_script_a.php', $return);
var_dump($return);
?>
/tmp/sbuzz$ php script_b.php
Could not open input file: doesnt_exist_script_a.php
int(1)
/tmp/sbuzz$
In this case I changed the script_b.php to try to run a script that doesn't exist, and I get the exit code 1 (it should be 2 if it completed successfully, because I changed the script_a above), but it also shows the error that it couldn't run the program.
You might want to try changing it to specifically run the full path to the PHP executable:
system('/usr/bin/php script_a.php')
or also the full path to the script as well:
system('/usr/bin/php /tmp/sbuzz/script_a.php')
You could also try specifically executing a program that will return 1, just as another data-point, such as:
system('false')
system('bash -c "exit 69"')
You might want to try an exit code other than 1, which is a common failure. That's why I did "exit 69" above. "false" will exit with 1.
Also, of course, try running the script_a.php directly:
/tmp/sbuzz$ php script_a.php
/tmp/sbuzz$ echo $?
2
/tmp/sbuzz$
The "$?" is the exit code of the last run command, at the shell prompt.
Try:
<?php
die(1);
?>
If that fails as well, check out the stdout of:
strace php script_a.php
Not sure if these problems are related, but you may take a look on exec always returns -1 (or 127) as i had a similar problem in the past... even if i didn't acually solved it.
In your case, it might be another problem, not sure how it would be reproduceable, but i've seen caeses where the return string for an unknown command would be the return string from bash (bash: command not found). On most servers i dont anything though. You may try and check the shell setup for the current user(i assume it would be www-data)
Taking in consideration of your comment that your problem is occuring in UNIX system when your script_b is something like
system('php script_a.php | tee myLogFile', $return);
You may use this syntax
system("bash -c 'php script_a.php | tee log.txt ; exit \${PIPESTATUS[0]}'", $return);
Do man bash and search for PIPESTATUS for more details.
I know this is an old thread, but I just had a similar problem.
The exit status was being set to 0 when I had the script run in the background, something like
system('php script_a.php &', $return);
Could you have been doing that but just generalizing for readability?
you need to be running as root or use sudo to access via php.
try something like this:-
system('sudo /usr/bin/php -f script_a.php', $return);
in your script_b.php
and edit /etc/sudoers to add the following line:-
apache ALL=(ALL) NOPASSWD: /usr/bin/php -f script_a.php
if php is not in /usr/bin/php change that reference
and also mention the full path of script_a.php file somthing like /var/www/html/script_a.php or path where it is physically located.
Thanks.

Custom php.ini file in when executing 'php' as a shell script

I'm running php as a shell script.
(I am not sure if "shell script" is correct. The file starts with #!/usr/bin/php.)
This works great. But the MongoDB class doesn't get loaded as the correct php.ini file (having extension=mongo.so) is not used.
How do I make it use that php.ini file?
I already tried #!/usr/bin/php -c /usr/local/lib/php.ini
But I still get the same error - Fatal error: Class 'Mongo' not found
What can be done?
Try putting php.ini in the same folder as the php binary. It seems to look there first.
I know this because I used a very powerful and useful command-line program called strace to show me what's really going on behind my back
$ strace -o strace.log php --version
$ grep php.ini strace.log
Strace digs out kernel (system) calls that your program makes and dumps the output into the file specified after -o
It's easy to use grep to search for occurrences of php.ini in this log. It's pretty obvious looking at the following typical response to see what is going on.
open("/usr/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/php.ini", O_RDONLY) = 3
lstat("/etc/php.ini", {st_mode=S_IFREG|0644, st_size=69105, ...}) = 0
Edit .bashrc located at your home directory and add this line:
alias php='php -c /path-to-custom/php.ini'
In this particular situation. I would
Check to see if the Mongo module is loaded (using extension_loaded() or class_exists())
If not loaded, try to load the Mongo module using dl()
If loading fails, display an error message so the admin can take care of it (STDERR or trigger_error()
Most distributions already ship different versions of php.ini for Web Servers and CLI. Are there other reasons to add another php.ini configuration for script XYZ (in addition to normal configuration)?
I came across this, because I had the same problem. Problem is there is more than one php.ini file used.
The one used by Apache is located in
/etc/php5/apache2/php.ini
This is the one that is modified to run MongoDB with extension=mongo.so.
However, when running a cron job, or from the terminal, it loads a different ini file. You can find this by using the line
grep php.ini strace.log
It is mentioned by thomas-peter.
The path where it displays '=3' is the php.ini file loaded when running the engine from the terminal, this ini file will need "extension=mongo.so" placed in it as well.
The other option is to use a small sh wrapper, something like this below in a myapp.sh file. Don’t forget to chmod +x on the script to run it.
#!/usr/bin/env sh
SOMEVAR='Yea Baby!'
export SOMEVAR
php -c /path/to/my/custom/php.ini /path/to/my/old_script.php
With the added bonus of being able to set or override environment variables pre-run.
This is a bit of a gotcha with PHP.
php -c /path/to/my/custom/php.ini works from the command line.
But try it in a script like this #!/usr/local/bin/php -c /path/to/my/custom/php.ini and your custom php won't load.
The Solution
Get rid of the space between -c and your path:
#!/usr/local/bin/php -c/path/to/my/custom/php.ini

Categories