Inside my automation.php controller, I have the following function:
public function deploy_test() {
echo json_encode(system("python --version"));
}
When the user wants to deploy a test, by clicking a test button in the webpage, he would be able to accomplish such a task.
However, when I click the test button, my output is:
""
Meanwhile, when I execute the same function with the command:
public function deploy_test() {
echo json_encode(system("ls -l"));
}
I'm getting:
total 32
drwxr-xr-x. 15 philippe philippe 4096 Mar 4 16:48 application
drwxrwxr-x. 2 philippe philippe 4096 Mar 4 17:28 css
-rw-r--r--. 1 philippe philippe 6357 Jan 30 11:53 index.php
drwxrwxr-x. 2 philippe philippe 4096 Feb 27 15:38 js
-rw-r--r--. 1 philippe philippe 2496 Jan 30 11:53 license.txt
drwxr-xr-x. 8 philippe philippe 4096 Jan 30 11:53 system
drwxr-xr-x. 12 philippe philippe 4096 Jan 30 11:53 user_guide
Could someone please help me to get that straighten out?
The problem is not with your code or PHP.
The problem is with your permissions.
php uses permissions which are set in the env-vars of apache.
Which is ideally set as :
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
under your apache2 / httpd conf file.
For example:
Try running:
<?= `whoami` ?>
via your shell and via your browser.
Your browser will probably say www-data and shell will say your username or if you are on AWS - default, you would get root
You do not have to use system() , use exec() instead.
We should be close as :
echo json_encode(exec("python --version"));
Performing operations will require you to have correct User and Groups set.
Look up for : In the shell, what does " 2>&1 " mean?
So your code should be :
echo json_encode(exec("python --version 2>&1"));
Hope it helps!
This works fine for my production server
public function deploy_test() {
echo json_encode(system("python --version 2>&1"));
}
with the output
Python 2.7.3
"Python 2.7.3"
Output of the unix command printed twice as system() itself outputs the result to browser. So exec() can be used in the place of system to avoid this.
public function deploy_test() {
echo json_encode(exec("python --version 2>&1"));
}
which outputs
"Python 2.7.3"
as expected.
I suspect it is not in the path. Try:
Type the full path to the python command (such as /usr/bin/python --version)
Find out with the command which, 'which python'
try executing your script from the command line, 'php script.php' => sometimes the web
server sets up things differently
make sure the error displaying is enabled with
ini_set('display_errors',1);
system returns only last line.
system
public function deploy_test() {
system("python --version", $out);
echo json_encode(implode($out));
}
It's a bit of hack, but you can find out the version number with 1 decimal even if you aren't allowed to execute python (which is the case with the 'user' CI).
//find python path
exec("which python", $path);
//show all subdirs in python
exec("ls -l ".$path[0]."*", $output);
$output = implode("\n", $output);
//preg match on version numbers
preg_match_all("#python(\d+(?:\.\d{1,2})?)#", $output , $matches);
$installed_versions = $matches[1];
//sort in reversing order
$versions_sorted_desc = array_reverse($installed_versions);
//latest version is element 0
$latest_version = $versions_sorted_desc[0];
echo $latest_version;
Related
On Ubuntu 18.04 I have a problem with editing PDF files - specifically search & replace strings.
I tried:
PHP mPDF Overwrite () do nothing.
perl CAM :: PDF 1.60 changepagestring.pl do nothing
sed, do nothing.
Does not work with compressed or decompressed PDF, Does not even work with PDF generated from mPDF.
UPDATE: after reinstalling libsodium mPDF works fine with PDF files generated fromm mPDF. For other PDF files issue still exist.
Also tried in var / www folders user / group www-data: www / data and in other folders / home e.g.
Any idea for bulk search & replace because I have over 1000 files to process?
The text in the files is readable. Check.
P.S. Search / Replace from the program and online service works with the same files.
Permission on files 0755 i 0777
root#sasa-ubuntu-1:/var/www/website.local/wp-content/test/2018/12# ls -la *.pdf
-rwxr-xr-x 1 www-data www-data 847451 Oct 18 12:21 clean.pdf
-rwxrwxrwx 1 www-data www-data 395527 Oct 17 21:41 My-First.pdf
-rwxr-xr-x 1 www-data www-data 838307 Oct 17 23:30 My.pdf
-rwxr-xr-x 1 www-data www-data 838167 Oct 18 12:24 New2.pdf
-rwxr-xr-x 1 www-data www-data 838167 Oct 18 01:20 New.pdf
-rwxrwxrwx 1 www-data www-data 270340 Oct 17 16:39 Test2.pdf
-rwxrwxrwx 1 www-data www-data 274022 Oct 17 16:39 Test1.pdf
-rwxr-xr-x 1 www-data www-data 838000 Oct 18 00:55 Test2.pdf
-rwxrwxrwx 1 www-data www-data 205679 Oct 17 23:44 test.pdf
Perl script allways return "Could not find title" nevermind of readability of file when I print $page variable (see images)
use CAM::PDF;
my $pdf = CAM::PDF->new('test.pdf'); # existing document
my $nump = $pdf->numPages();
#print $nump;
my $page = $pdf->getPageContent(1);
print $page;
# $page now holds the uncompressed page content as a string
# replace the text part
if ($page =~ s/Wagner/SoundTech/g) {
$pdf->setPageContent(1, $page);
}
else {
die "Could not find title\n";
}
$pdf->cleanoutput('Test2.pdf');
A lot of files ends on this way.
The string that I try to find is "Wagner International Music Examinations" or only "Wagner"
mPDF and CAM-PDF are properly installed without warnings and erros and with all dependencies, I hope.
Ubuntu 18.04
mPDF version 8.0
PHP 7.2
Perl 5.26.1
CAM-PDF version 1.60
mPDF occasionally have bug with Overwrite() function, I found on their github community.
Any suggestion or another way for bulk search & replace in PDF files?
Here is a hack that currently works almost for your case (I will come back later and try improve this):
use feature qw(say);
use strict;
use warnings;
# the PDF uses a non-standard encoding so it does not help to use UTF-8
# use open qw(:std :encoding(UTF-8));
use utf8;
use CAM::PDF;
my $fn = 'test.pdf'; # uncompressed file..
my $save_fn = 'test2.pdf';
my $pdf = CAM::PDF->new($fn);
my $nump = $pdf->numPages();
my $match = 0;
my $replace = '[(\x{a9} SoundTech International Music Examinations)]TJ';
for my $i (1..$nump) {
my $page = $pdf->getPageContent( $i );
# replace the text part
if ($page =~ s/\[\(\x{a9}\).*?\]TJ/$replace/g) {
$match = 1;
$pdf->setPageContent($i, $page);
}
}
if ( $match ) {
$pdf->cleanoutput($save_fn);
say "Save $save_fn ..";
}
else {
say "No match";
}
So this is my code for the raspberry pi to get a still shot from the raspicam and save it on a directory,
<?php
exec('raspistill -n -hf -o /var/www/img/image.jpg --timeout 1');
?>
I have given the ownership and the permission to read/write in that forlder using -R. so my ls -al in /var/www is this
drwxr-xr-x 3 www-data www-data 4096 Jun 19 08:05 .
drwxr-xr-x 12 root root 4096 Jun 19 05:54 ..
-rwxrwxrwx 1 www-data www-data 74 Jun 19 08:30 getImg
drwxrwxrwx 2 www-data www-data 4096 Jun 19 09:21 img
-rw-r--r-- 1 root root 70 Jun 19 10:07 index.php
getImg is the script i tried to run the script as a file like shell_exec('/bin/bash ./getImg'); that also doesn't work.
i have added /bash/bin and tried to run the script without using the script file too but that doesn't get the results.
How ever when i try to run the php file in the terminal, it creates the image as it normally should. So i figure this must be a permission issue, but what else should i do with the permissions? I have given all the rights to the directory.
EDIT
So I have found a workaround to this. since I don't know what the cause for the problem, i'd not mark this as an answer, but please vote it to appear at the top.
I now execute the script using the cgi scripts. I have created a shell script in the /usr/lib/cgi-bin/
#!/bin/bash
echo "Content-type:text/html\n"
sudo raspistill -vf -n -o /var/www/img/image.jpg --timeout 1200 --metering matrix
echo "Status: 204"
I saved this as capture and made this executable, did nothing with the permissions though.
sudo chmod +x capture
now when i open the link http://192.168.1.85/cgi-bin/capture the browser will still get me a 500 internal server error message. how ever, the image would still be created.
I would now need to get the 500 internal server error to be fixed.
[I'd add this as a comment but don't have enough points for it]
if you use the optional parameters $output and $return_var to capture the output and return value what do you get?
string exec ( string $command [, array &$output [, int &$return_var ]] )
does your command rely on environment variables that may be available when you run it as your user but not as www-data? (you can use the env command to check that)
does it still work if you run it via terminal after switching user to www-data?
I;m trying to run phantomjs from php. To check correct path and permissions, as first I execute this commands:
$output = shell_exec('ls /opt/phantomjs-1.9.2-linux-x86_64/bin/ -l');
echo "<pre>$output</pre>";
Result:
-rwxrwxrwx. 1 root root 38526976 Sep 7 11:17 phantomjs
drwxrwxrwx. 2 root root 4096 Feb 10 15:44 savedpages
-rwxrwxrwx. 1 root root 803 Jan 19 18:36 saveonepagelin.js
-rwxrwxrwx. 1 root root 4074 Jan 19 19:00 test.js
But when I run:
$output = shell_exec('/opt/phantomjs-1.9.2-linux-x86_64/bin/phantomjs --version');
echo "<pre>$output</pre>";
Output is empty :( why? Thanks!
My first guess would be a permission problem. Is the www-data user (or whichever user your server is called) allowed to run the program?
Do you get anything returned if you place $output in var_dump() instead?
I.e.
$output = shell_exec('/opt/phantomjs-1.9.2-linux-x86_64/bin/phantomjs --version');
var_dump($output);
I got the same error, and I try to modify the dir where I execute the phantomjs and set the mode with 777, then it worked. I guess the root cause if the owner of the php-fpm doesn't have right to write image into the dir.
my code for refer:
$output = passthru('phantomjs echarts-convert.js -options ' . $options . ' -outfile line.png');
echo $output;
I have to execute a php script (a.php) in the background. I tried this but it's not working:
<?
$cmd = "php /home/megad404/www/prove/a.php &> /dev/null &";
exec('/bin/bash -c "'.$cmd.'"',$output,$return);
if($return===0)
{
echo 'Successful';
}
else
{
echo 'Unsuccessful';
}
?>
It returns "Successful" but it doesn't execute a.php
a.php:
<?
file_put_contents(date("s"),"");
sleep(5);
file_put_contents(date("s"),"");
sleep(5);
file_put_contents(date("s"),"");
?>
a.php writes a file every 5 second and it works fine, except if I try to execute it in the background with the first script.
You can try adapt mi script.
Look a command shell_exec() not exec(). First return all , second only last line.
function run_in_background($Command, $Priority = 0) {
if($Priority)
$PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
else
$PID = shell_exec("nohup $Command > /dev/null & echo $!");
return($PID);
}
//Verifies if a process is running in linux
function is_process_running($PID) {
exec("ps $PID", $ProcessState);
return(count($ProcessState) >= 2);
}
and example
$PIDPHP=run_in_background("php -S 127.0.0.1:18086 ".__DIR__."/index.php"); // or any other process.
if (is_process_running($PIDPHP)){
exec("kill $PIDPHP");
}
You could also look into using real Posix/PCNTL functionality to actually detach the script to background, eg. with pcntl_exec and pcntl_fork(). This is after my opinion the right way to handle background scripts that runs for a longer period of time as you can communicate with the child/process to get updates, status and so on and even have them understand real signal handling.
PCNTL - http://www.php.net/manual/en/book.pcntl.php
POSIX - http://www.php.net/manual/en/book.posix.php
Cheers
This just worked for me:
<?php
$cmd = "/usr/bin/php /home/auser/a.php &> /dev/null &";
exec($cmd,$output,$return);
sleep(30);
if($return===0)
{
echo 'Successful';
}
else
{
echo 'Unsuccessful';
}
?>
I saved it as runa.php and ran it from the command window as php runa.php.
It produced 3 files.
running a.php also worked from the cron job:
]$ crontab -l
18 * * * * /usr/bin/php /home/auser/a.php
I put the script in a web directory and find that I have some writing problems. What can you see in the server log?
sudo tail -f /var/log/httpd/error_log
And what if you hit a.php from the web browser? Because you mention the script is 755, but how about the directory. Maybe it needs to be 775 or 777 for testing so that the script can write a file?
For testing I created a sub directory "output" and changed a.php
<?php
ini_set('date.timezone','America/New_York'); //without this it makes extra messages
error_log("a.php putting contents", 0);
file_put_contents("output/".date("s"),"");
sleep(5);
file_put_contents("output/".date("s"),"");
sleep(5);
file_put_contents("output/".date("s"),"");
error_log("a.php done", 0);
?>
It was unable to write files until I gave write permission to the ouput folder
sudo chmod 777 /var/www/html/output
Then I found out the apache user is writing the files:
~]$ sudo ls -l /var/www/html/output/
total 0
-rw-r--r--. 1 apache apache 0 Apr 18 11:38 00
-rw-r--r--. 1 apache apache 0 Apr 18 11:38 05
-rw-r--r--. 1 apache apache 0 Apr 18 11:37 55
So I changed the owner of output, in order to tone down the permissiosn again.
~]$ sudo ls -lu /var/www/html/ | grep output
drwxr-xr-x. 2 apache root 4096 Apr 18 12:21 output
This also works now:
~]$ sudo ls -l /var/www/html/output
total 0
-rw-r--r--. 1 apache apache 0 Apr 18 12:21 44
-rw-r--r--. 1 apache apache 0 Apr 18 12:21 49
-rw-r--r--. 1 apache apache 0 Apr 18 11:37 55
as the problem states..
when i do
exec("ls -ltr > output.txt 2>&1",$result,$status);
its different from the normal output. An extra column gets added. something like
-rw-r--r-- 1 apache apache 211 Jul 1 15:52 withoutsudo.txt
-rw-r--r-- 1 apache apache 0 Jul 1 15:53 withsudo.txt
where as when executed from the command prompt its like
-rw-r--r-- 1 apache apache 211 2010-07-01 15:52 withoutsudo.txt
-rw-r--r-- 1 apache apache 274 2010-07-01 15:53 withsudo.txt
-rw-r--r-- 1 apache apache 346 2010-07-01 15:55 sudominusu.txt
-rw-r--r-- 1 apache apache 414 2010-07-01 15:58 sudominusu.txt
See the difference. So in the first output , my usual awk '{print $8}' fails.
I was facing the same problem with cron. But solved it by calling
./$HOME/.bashrc
in the script. But not happening using php. If somehow i can "tell" php to "exec" from the usual environment. Any help would be appreciated.
In your login shell, ls is probably aliased so that it prints another date. This would be in your .basrc or .bash_profile.
Explicitly pass the --time-style= option to ls to ensure that it prints the date in the expected format when using PHP.
I guess you are only interested in the file names and you want to sort with reverse time.
Try this:
ls -tr1 > output.txt 2>&1
You'll get a list with only the file names, so you don't need awk at all.
Another solution is to specify the time format with "--time-style iso". Have a look at the man page
That's not an extra output, that's a difference in formatting the date. Apparently you have a different locale set in PHP and in bash ("command prompt").
(in bash, running export LANG=C or export LANG=en_US gives the result with three-letter month name)
The output of ls is heavily dependent on the environment (e.g., LANG being the important variable here). Why not use a combination of scandir, stat, and krsort?
function ls($dir_name) {
$finfo = array();
foreach (scandir($dir_name) as $file_name) {
$s = stat(join('/', array($dir_name,$file_name)));
$finfo[$file_name] = $s['mtime'];
}
krsort($finfo);
return array_keys($finfo);
}
This will be safer and a lot more efficient than shelling out to ls. Not to mention that you get the benefit of being about to customize the sorting and filter the results in ways that are difficult to do inside of an exec.
BTW: I am by no means a PHP expert, so the above snippet is likely to be incredibly unsafe and full of errors.