The following line was the best I read to this problem: "You need to disable safe mode in the php.ini located in the \Apache2\bin folder, not the php folder. Restart Apache2 service right after to load the new settings."
The solution is:
stop all services from Wamp-Server and close the programm
Open .../wamp/bin/apache/Apache2../bin/php.ini
copy php.ini to desktop and open it
set safe_mode_exec_dir (line after = is empty, so IT IS ON!!!) set it off!
save
copy back to dir (maybe you need admin rights)
start wamp-server
enjoy exec() and co.
The following line was the best I read to this problem: "You need to disable safe mode in the php.ini located in the \Apache2\bin folder, not the php folder. Restart Apache2 service right after to load the new settings."
The solution is:
stop all services from Wamp-Server and close the programm
Open .../wamp/bin/apache/Apache2../bin/php.ini
copy php.ini to desktop and open it
set safe_mode_exec_dir (line after = is empty, so IT IS ON!!!) set it off!
save
copy back to dir (maybe you need admin rights)
start wamp-server
enjoy exec() and co.
I was having the same problem and tried a lot of solutions out there. What worked out for me was running XAMPP as Admin.
PHP shell_exec() executing in C:/xampp/htdocs and not in C:/xampp/htdocs/folder - Stack Overflow
[SOLVED] shell_exec() problems
python - Why doesn't shell-exec() run in PHP? - Stack Overflow
php - The shell_exec and exec() commands don't work on linux Ubuntu in my localhost Ububtu 20.04 - Stack Overflow
Videos
1) Check the security setup
Can shell_exec() be run or not? If it can't then it's because
you are having some security settings enabled.
The problem is that shell_exec() and exec() can be disabled
for security reasons. This can be changed by editing
PHP's disable_functions option.
INI settings are usually stored in specific *.ini files under the
/etc/php/* directories. So you have to look for some settings
in there. You’ll find several INI settings, depending on how PHP is
run. To find them :
find /etc/php/ -iname 'php.ini'
This could output something like this :
/etc/php/8.2/fpm/php.ini
/etc/php/8.2/apache2/php.ini
/etc/php/8.2/cli/php.ini
/etc/php/8.2/cgi/php.ini
To see the settings and which INI file is loaded, add this at the beginning of your script and call it via your web server :
phpinfo();
die();
You'll see all the loaded INI files and what is set on the
disable_functions option.
/etc/php/8.2/cli/php.ini is probably setting disable_functions
to an empty string, meaning that in command line there's no
restriction. But for the other INI files, this option might contain
a list of functions that you won't be able to run. Edit this option
if needed. But be always aware that giving your server the ability
to run some binaries can lead to some security issues if your app
is taking some user input to build the command.
Apache configuration can also set some
PHP settings,
just for a specific Virtual Host. So have a look at them if you can't
find something in the php.ini files.
Depending on your PHP setup, you may also have to check safe_mode and suhosin.executor.* if you have the Suhosin hardening module installed.
2) Verify that you can run shell_exec
There are several ways to run a binary.
shell_exec
is equivalent to the built-in
backtick operator.
So if shell_exec is listed in the disable_functions option then
you won't be able to use the backtick operator.
If you get an error 500 then it's typically because you cannot run
shell_exec. If you check /var/log/nginx/error.log or
/var/log/apache2/error.log with this command :
sudo tail -f /var/log/{apache2,nginx}/error.log
It will print both logs until you press CTRL+C. You may see this error :
PHP Fatal error: Uncaught Error: Call to undefined function shell_exec()
PHP also offers
exec(),
passthru(),
system(),
and the
proc_*()
functions. So you've got several possibilities to try and run your
command.
Have a try with a simple PHP code :
<?php
header('Content-Type: text/plain; charset=utf-8');
echo 'PHP user given with the "id" command: ' . `id`; // equivalent to shell_exec('id');
echo 'System date is ' . `date --iso-8601=seconds`;
This should output RAW text in your browser with :
PHP user given with the "id" command: uid=33(www-data) gid=33(www-data) groups=33(www-data)
System date is 2023-09-29T11:50:28+00:00
3) Use a full path to the binary
When shell_exec() is run from the web server, it's rather common
that the binary isn't found in the PATH.
Usually, the www-data user running PHP won't even have a shell.
But this user can normally run some binaries, except if some settings
at point 1 is blocking it.
To find the full path to a binary, use the which command :
which wkhtmltopdf
This should output the full path to the binary. Certainly something
such as /usr/bin/wkhtmltopdf.
Now replace your PHP code with the full path to the binary:
header('Content-Type: text/plain; charset=utf-8');
echo shell_exec('/usr/bin/wkhtmltopdf --version');
Does it print wkhtmltopdf 0.12.6 like expected?
If no, then we have to investigate more at the next point.
4) Get the execution output and find errors
This can be done with the help of exec(), passthru() or system()
as they all return the execution status code.
With the proposition of Volkerschulz, we'll also redirect the standard error stream to the standard output stream so that we can see some details that may have only be printed to the error stream.
This is done by redirecting stderr (2) into stdout (1) by adding 2>&1 after your command.
Just as info, stdin is 0.
In PHP, this becomes :
<?php
header('Content-Type: text/plain; charset=utf-8');
$command = '/usr/bin/wkhtmltopdf --wrong-option 2>&1';
$last_line = exec(
$command, // The command to execute.
$output, // A variable that will be filled with an array of all the lines returned.
$result_code // The return status of the executed command.
);
var_export([
'$command' => $command,
'$output' => $output,
'$last_line' => $last_line,
'$result_code' => $result_code,
]);
This outputs :
array (
'$command' => '/usr/bin/wkhtmltopdf --wrong-option 2>&1',
'$output' =>
array (
0 => 'Unknown long argument --wrong-option',
1 => '',
2 => 'Name:',
3 => ' wkhtmltopdf 0.12.6',
...
...
95 => '',
),
'$last_line' => '',
'$result_code' => 1,
)
Now I'm able to see that I got a $result_code of 1 instead of 0.
In case the executable is having other errors, you'll see them in
the $output array as the stderr stream should be visible. This
should help you find how to fix the issue. Probably some other
security problems due to the fact the www-data user might be
missing some rights, paths or whatever.
PS: On my Vagrant box of Ubuntu 22.04, I managed to run wkhtmltopdf without errors on both Apache and NGINX.
Don't forget also that your www-data user should have write
access to the destination folder where you are producing the PDF file.
5) Try re-installing wkhtmltopdf and/or use a PHP wrapper
You might have to re-install wkhtmltopdf if it's not properly working :
sudo apt remove wkhtmltopdf
sudo apt autoremove
sudo apt install wkhtmltopdf
You can also try using a PHP wrapper library for wkhtmltopdf called Snappy. It might be useful.
6) Switch to an alternative in pure PHP if necessary
Perhaps you won't manage to make wkhtmltopdf work that easily.
It's a pity as it's effectively a fast and reliable solution.
But to create a PDF from HTML you could also use the Dompdf PHP library. I've used it in the past and was happy with it.
Instead of
shell_exec($wkhtmltopdfCommand);
try
$result = passthru($wkhtmltopdfCommand . ' 2>&1');
var_dump($result);
and it should tell you what's wrong.
The PHP shell_exec will try to run the command in the host system. Therefore you cannot run linux command on windows.
If you really want to try running that in windows and you have windows 10 maybe you can try using wsl ( windows subsystem linux )
Thanks to @SKos and @lit I came to the solution which is simply install Windows Subsystem for Linux and then prepend wsl to the linux command.
shell_exec('wsl sed "s/abc/def/"')
Hi there
I'm working on an Arduino project and I want to make a connection to a serial port with PHP to send/receive data, after a lot of googling I couldn't figure it out, so I decided to use the shell_exec() function to run a python program that does this job, and the shell_exec() runs commands like "ls, pwd", but when I run python program it doesn't work, so how can I run the python program?
I use Ubuntu 20.04 and XAMPP as my local server.
PHP code:
<?php
$output = null;
$output = shell_exec("./turnled.py");
echo $output;
?>python code:
#!/usr/bin/env python3
import serial
import time
arduino_port = serial.Serial("/dev/ttyACM0", 115200)
time.sleep(5)
arduino_port.write(b'1')
print("OK")
arduino_port.close()the .py file is executable.