Executing a linux program from php - php

Using the following software: http://silvercoders.com/en/products/doctotext/
I got it to work on my Window's machine using this following code:
<?php
$file = 'C:\xampp\htdocs\SMF\sdsdssss.docx';
$content = exec( 'C:\xampp\htdocs\SMF\doctotext\doctotext.exe /c '. $file , $output );
var_dump( $output );
However, when I tried it on my Centos machine, using the linux x86_64 version of the software, I cannot get it to work. (Yes, my machine is x86_64 too)
I tried:
<?php
$file = '/home/***/public_html/downloads/test_doc.docx';
$content = shell_exec( '/home/***/public_html/doctotext/doctotext.sh \c '. $file , $output );
But nothing outputs. What is the equivalent execution format for those running centos.
Please advise

First of all shell_exec() does not take a second argument. I think you are confusing the function with exec() which does take more than one argument:
exec('/home/***/public_html/doctotext/doctotext.sh \c '. $file, $output, $return);
From the documentation for shell_exec():
This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution failures using this function. exec() should be used when access to the program exit code is required.
Second, I think you first should check so the shell script has execute permissions. You can set the correct permissions using:
chmod +x /home/***/public_html/doctotext/doctotext.sh
Depending on what the script is doing you might also need to run it with root privileges:
sudo php -f myscript.php
If you are running the script through your browser you should also make sure so that the path to the shell script is readable by the webserver.
It would also be nice if you enabled error reporting and check if you get any error messages when running your script.

Related

How i can run function exec in PHP

I can't add * to my code to find file
this code work
exec("mediaconvert -t wav -i /home/20220228/11/23401.rec -o /var/www/html/test.mp3");
if i add a the *, it don't work
exec("mediaconvert -t wav -i /home/20220228/11/*01.rec -o /var/www/html/test.mp3");
p.s. in path is only one file, when i try execute this code from shell it work. Pls help me)
Filename expansion and other bash-specific features may/will not work in other shells (e.g. standard POSIX). If your command with * is not executed in bash/compatible, it won't work as expected. You need to verify the environment/shell that your PHP installation executes commands in.
Run the following test script:
<?php
exec('echo "$SHELL"', $out);
var_dump($out);
When I run the PHP script directly on CLI, I get "/bin/bash" for the shell that's called. When I run it via browser, curiously I get "/sbin/nologin" instead. There are different environments for user apache that executes PHP via browser calls, and the "actual" user logging in via SSH. Bash shell is not available for the Apache user by default.
These results are from a Centos7 server with Apache 2.4/PHP 8.1.4 running. Your mileage may vary. Bottom line: if the command you are executing depends on bash-specific features, it must execute in a bash environment, or another shell that supports the required features.
If bash is not available, your other option is using e.g. glob to get files matching the pattern in your directory, and then loop over them while executing the command for each specific file.
Edit: As pointed out by #Sammitch (see comments), /sbin/nologin is a common "shell name" choice for non-login users, and most likely uses /bin/sh. This should still allow for filename expansion/globbing. Testing browser script call with exec('ls *.php', $out); the wildcard functions as expected.
You may find this question/answer relevant: Use php exec to launch a linux command with brace expansion.
I recommend you do the opposite. First, get the files you want to input then you exec. For instance:
$input_files = ...
exec("mediaconvert -t wav -i " . $input_files . " -o /var/www/html/test.mp3");
You can try to find files with glob() function and after that you can use exec(). You can try a similiar solution with the following code:
$input_files = '/home/20220228/11/*01.rec';
foreach (glob($input_files) as $filename) {
exec("mediaconvert -t wav -i " . $filename . " -o /var/www/html/test.mp3");
}

unable to execute python script from php

I want to execute Python script from PHP file. I am able to execute simple python script like:
print("Hello World")
but when I want to execute following script, nothing happens
from pydub import AudioSegment
AudioSegment.converter = "/usr/bin/ffmpeg"
sound = AudioSegment.from_file("/var/www/dev.com/public_html/track.mp3")
sound.export("/var/www/dev.com/public_html/test.mp3", format="mp3", bitrate="96k")
and same script works fine when I execute it from terminal. here is my php script:
$output = shell_exec("/usr/bin/python /var/www/dev.com/public_html/index.py");
echo $output;
I have also tried following method but no luck:
$output = array();
$output = passthru("/usr/bin/python /var/www/dev.com/public_html/index.py");
print_r($output);
please help me
PHP's passthru function does not have the elegant method for which you may be searching of passing environment variables. If you must use passthru, then export your variables directly in the command:
passthru("SOMEVAR=$yourVar PATH=$newPATH ... /path/to/executable $arg1 $arg2 ...")
If you are inclined toward shell_exec, you may appreciate putenv for the slightly cleaner interface:
putenv("SOMEVAR=$yourVar");
putenv("PATH=$newPATH");
echo shell_exec("/path/to/executable $arg1 $arg2 ...");
If you are open to a more robust (if tedious) approach, consider proc_open:
$cmd = "/path/to/executable arg1 arg2 ..."
# Files 0, 1, 2 are the standard "stdin", "stdout", and "stderr"; For details
# read the PHP docs on proc_open. The key here is to give the child process a
# pipe to write to, and from which we will read and handle the "passthru"
# ourselves
$fileDescriptors = array(
0 => ["pipe", "r"],
1 => ["pipe", "w"],
2 => ["pipe", "w"]
);
$cwd = '/tmp';
$env = [
'PATH' => $newPATH,
'SOMEVAR' => $someVar,
...
];
# "pHandle" = "Process handle". Note that $pipes is new here, and will be
# given back to us
$pHandle = proc_open($cmd, $fileDescriptors, $pipes, $cwd, $env);
# crucial: did proc_open work?
if ( is_resource( $pHandle ) ) {
# $pipes is now valid
$pstdout = $pipes[ 1 ];
# Hey, whaddya know? PHP has just what we need...
fpassthru( $pstdout );
# Whenever you proc_open, you must also proc_close. Just don't
# forget to close any open file handles
fclose( $pipes[0] );
fclose( $pipes[1] );
fclose( $pipes[2] );
proc_close( $pHandle );
}
Acc to your reply, as you want to execute the python script from PHP
I was able to execute it using the following code
$command = escapeshellcmd('/var/www/yourscript.py');
$output = shell_exec($command);
echo $output;
Please use the above PHP code with the same python script.
Try to run the python script as a GCI script first to make sure it is working and set the permissions to public directory and script as I mentioned before
===================old ans============================
From what you asked, I guess this is what you are trying to do is that you are trying to run it as a CGI script like http://localhost/yourscript.py
And why are you using PHP to execute python script when you can run it directly as a CGI script?
here is what you need to do to make it work like a web page:
enable python CGI in apache ( or in the web server you are using ).
put the script in CGI configured directory
add proper code to your script to make it work as a CGI script
#!/usr/local/bin/python
from pydub import AudioSegment
AudioSegment.converter = "/usr/local/bin/ffmpeg"
sound = AudioSegment.from_file("/var/www/dev.com/public_html/track.mp3")
sound.export("/var/www/dev.com/public_html/test.mp3", format="mp3", bitrate="96k")
print "Content-type: text/html"
print
print ""
print ""
print ""
print "Done/ you can perform some conditions and print useful info here"
print ""
Give permissions to the script and make the public directory writable
Access the script http://localhost/your-path-to-script.py
I was able to run this properly.
let me know if that's not your case if you want something else
In my case, I did this code.
<?php
chdir('/home/pythontest') ; // python code dir
$commandline="/usr/bin/python3 test.py parameter" ;
exec($commandline, $output, $error) ;
echo $output ;
?>
If you need to set some environments for python, add environment vars like this.
$commmandline="LANG=en_US.utf8 LC_ALL=en_US.utf8 /usr/bin/python3 ..." ;
and check the httpd log.
Check this:
The apache user has to be in sudoers file, better you don't give sudo to apache instead give apache (www-data) user right to run your python program
put first line in your python script: #!/usr/bin/env python so the script knows which program to open it with..
then,
change group:
chgrp www-data /path/to/python-script.py
make it executabe:
chmod +x /path/to/python-script.py
then try it:
shell_exec("/path/to/python-script.py");
I hope this will work! :)
You can also exec ffmpeg directly without python:
$output = shell_exec("/usr/bin/ffmpeg -i in.mp3 -b:a 96k out.mp3");
echo $output;
ffmpeg docs
Answered in 2022.
In php 8.0 and above the following method worked. Above answers are very useful but i am compiling few extra steps here.
PHP Code.
$output = shell_exec("python3 /var/www/python/test.py");
print_r($output);
exec('python3 --version 2>&1', $output);
var_dump($output);
Trying both shell_exe and exec
Make sure the python file has executable permission and added to www-data group (if its ubuntu/debian systems) . sudo chmod +x test.py and sudo chgrp www-data test.py
Make sure the php.ini has disabled_functions line commented or empty.
sudo vim sudo vim /etc/php/8.0/cli/php.ini
sudo vim sudo vim /etc/php/8.0/apache2/php.ini
For both.
I compiled a simple video to make sure others dont spend more time figuring out the problem. https://youtu.be/t-f6b71jyoM

Why php exec, system and passthrough functions stopped working if FPM is enabled

Hello Guys I am average in server configuration.I am using php exec function to run some commands in my website.But it stopped working if i enable PHP-FPM.
Anybody knows why it cause this issue ?
Below is php function to run the command
$cmd="pdftk " . $pdf_to_fill . " fill_form " . $fdf_file . " output $outputfile 2>&1";
exec($cmd, $output, $return_var);
Thanks in advance for your help.
This can be a few things, first, try to confirm if exec is enabled, if safe mode is enabled, and if we're in a jailed shell.
The first two can be done with this script, just see what it outputs when you access it:
if(function_exists('exec')) {
echo '<h1>exec is available.</h1>';
}
if( ini_get('safe_mode') ){
echo '<h1>Safe mode is on.</h1>';
}
The jailed shell is a little harder to detect, but running var_dump(scandir('/bin/')) will give an indication, if it has a lot less files in it than if your run ls -ltr /bin from the command line, then you're in a jailed shell.
Also, it may be worth using the full path of the pdftk binary, and if it still doesn't work, try running is_executable on the path for pdftk.

Not able to run wkhtmltopdf commad through shell_exec() function in php but same command works on command line

I'm in trouble and that much confused about a php shell_exec command.
When the command is execute by PHP I have no error but the execution fails. If I use exactly the same command from a terminal it works.
Here's the command :
/usr/bin/wkhtmltopdf --lowquality --dpi 300 --encoding utf-8 "/tmp/knplabs_snappyxa9otq.html" "/tmp/knplabs_snappyv3pD7h.pdf"
When I lauch this from a terminal :
$ /usr/bin/wkhtmltopdf --lowquality --dpi 300 --encoding utf-8 "/tmp/knplabs_snappyWG9XTd.html" "/tmp/knplabs_snappyv3pD7h.pdf"
Loading page (1/2)
Printing pages (2/2)
Done
But from my php script :
// Construct the previous command
$command = $this->buildCommand($url, $path);
../..
shell_exec($command);
../..
$content = file_get_contents($path);
../..
I've test the output of shell_exec, it's empty.
The log :
Warning: file_get_contents(/tmp/knplabs_snappyv3pD7h.pdf): failed to open stream: No such file or directory in /*****/lib/snappy/SnappyMedia.class.php on line 64
No permission pb in the /tmp directory :
$ ls -la /tmp
total 448
drwxrwxrwt 16 root root 4096 mars 12 21:51 .
../..
I've tried avec the PHP exec() function to get error informations, I just get an "1" error code in return_var and nothing in output.
For information this issue appear on my test server, my desktop computer but not on my notebook. All the 3 are with sames PHP, Apache, Mysql versions.
I don't understand anything ...
Thanks for any help, I'm loosing my mind.
David.
I've found the solution here : Executing wkhtmltopdf from PHP fails
Thanks to Krzychu.
First to get information from the shell_exec command add " 2>&1" at the end of the command. In that way you will get information in return of the command :
$no_output = shell_exec($command);
echo $no_output; // nothing
$output = shell_exec($command . ' 2>&1');
echo $output; // in my case : "cannot connect to X server"
The solution :
Not use the wkhtmltopdf ubuntu package (0.9.9-4)
Use the official package from the Wkhtmltopdf download page
So no need to install xvfb ! (I've seen this advice many times)
Looks like a user's permissions issue.
When you run the command from the terminal, it is the user account, currently used, which does have the right permissions, to run a command in /usr/bin, and execute the specific file.
When you run it from the php script, it is the http server account on your system, which needs the permission to execute the file in /usr/bin. Usually this is the apache user.
How you should setup permissions depends on your system. Just remember that what is allowed for apache, is allowed for anyone accessing your http server.
I have had this problem for ages and adding . ' 2>&1' after the $command has somehow solved the problem.
this:
$output = shell_exec($command . ' 2>&1');
instead of:
$output = shell_exec($command);
No idea why but it works and I'm grateful.
Is it a shared hosting? It seems like shell_exec is a restricted function. Try running error_reporting(E_ALL); ini_set('display_errors', 1); before calling shell_exec.
I stumbled upon the same Problem, in my case an absolut Path in the exec Command like /var/www did not work, I had to use relative Paths from the point where I executed the php File.
I also wanted to notice, that it did not work using shell_exec, however it worked using normal exec command, not sure wheres the difference here.

PHP and Apache : shell_exec(wkhtmltopdf with xvfb) command doesn't work

I try to run the wkhtmltopdf (0.11.0 rc1) with php (5.4.2) on apache (2.4.2).
When I try to launch wkhtmltopdf-i386 --use-xserver http://www.google.com google.pdf 2>&1, I can find my pdf. Here my php code
<?php
$cmd= '/usr/bin/wkhtmltopdf-i386 http://www.google.com google.pdf 2>&1';
$ret = shell_exec($cmd);
echo $ret;
?>
It works with apache and as command line php test.php.
Because my target page contains many images and some "heavy" js charts. I have got a Segmentation Fault with the wkhtmltopdf command when I try to turn it into pdf.
The only way to make it work is to use xvfb as X11 emulator. The code looks like this :
<?php
$cmd= '/usr/bin/xvfb-run /usr/bin/wkhtmltopdf-i386 --use-xserver http://www.google.com google.pdf 2>&1';
$ret = shell_exec($cmd);
echo $ret;
?>
This script works with the command line php test.php but it doesn't work with apache. If I take a look into the apache's process with htop, I can see that there are two process (with php test.php) :
xvfb
wkhtmltopdf
When I launch with apache I have only xvfb process. It finish by a timeout from apache because it's waiting the wkhtmltopdf process.
I can make it works with apache (2.2.21) and php (5.3.10).
Is there something that I'm missing ? Maybe something in the apache's config-files ?
I was having the same problem. I was using the exec function, but the same applies to shell_exec. The function execution was disabled in php.ini.
SOLUTION: Remove the shell_exec string from the disable_functions at php.ini file.
I am not sure why your second version is not callable from Apache (must not be using the same shell, since shell_exec uses a shell?), but as a work-around could you (from Apache PHP) shell_exec("php test.php"); and get your intended result?
Perhaps also try one of the other process execution functions such as pcntl_exec.
it's mostly because of ownership and permissions, try
su www-data (for debian)
php test.php
you'll probably see the error.

Categories