If you are not the root on the machine, and exec() function is disabled, then you can't enable it by yourself.

See http://php.net/manual/en/ini.core.php#ini.disable-functions

disable_functions string

This directive allows you to disable certain functions for security reasons. It takes on a comma-delimited list of function names. disable_functions is not affected by Safe Mode.

Only internal functions can be disabled using this directive. User-defined functions are unaffected.

This directive must be set in php.ini For example, you cannot set this in httpd.conf.

Answer from Adam on Stack Overflow
Top answer
1 of 6
12

The Apache’s user www-data need to be granted privileges to execute certain applications using sudo.

  1. Run the command sudo visudo. Actually we want to edit the file in etc/sudoers.To do that, by using sudo visudo in terminal ,it duplicate(temp) sudoers file to edit.
  2. At the end of the file, add the following ex:-if we want to use command for restart smokeping and php command for another action in your question,

www-data ALL=NOPASSWD: /etc/init.d/smokeping/restart, usr/bin/php

(This is assuming that you wish to run restart and php commands using super user (root) privileges.And you use php command in usr/bin/ path )

However, if you wish to run every application using super user privileges, then add the following instead of what’s above.You might not want to do that, not for ALL commands, very dangerous.

www-data ALL=NOPASSWD: ALL

3.After edit the sudoers file(by visudo we edit the temp file of sudoers so save and quit temp file(visudo) to write in sudoers file.(wq!)

4.That’s it, now use exec() or shell_exec in the following manner inside your xxx.phpscript.keep remember to use sudo before the command use in the php script.

ex:-

exec ("sudo /etc/init.d/smokeping restart 2>&1");

or

shell_exec("sudo php -v"); 

So in your problem,add the commands that you wish to use in to the step no (2.) as I add and change your php script as what you want.

here is the same problem as yours https://stackoverflow.com/a/22953339/1862107

2 of 6
5

Try specifying the entire path to the php binary.. Eg, /usr/bin/php

If you don't know it, find it using: which php

Discussions

Allow PHP/Apache to shell_execute commands on Ubuntu - Stack Overflow
I'm trying to execute a command through PHP with shell_exec. The PHP file is hosted by Apache on my Ubuntu server. When I run this: echo shell_exec("ps ax | grep nginx"); Then I get to see data. ... More on stackoverflow.com
🌐 stackoverflow.com
php - The shell_exec and exec() commands don't work on linux Ubuntu in my localhost Ububtu 20.04 - Stack Overflow
First try a simple shell_exec('ls -al') to see if it lists the current directory. Advance step by step to investigate where the problem is. 2023-09-28T20:10:18.28Z+00:00 ... I've run the code and it returns this: /usr/bin/wkhtmltopdf: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/bin/wkhtmltopdf) /usr/bin/wkhtmltopdf: What should I do? 2023-09-28T16:32:18.997Z+00:00 ... This means, the php (apache) user (in Ubuntu ... More on stackoverflow.com
🌐 stackoverflow.com
How can I enable shell_exec?
Hello. Please, friends and experienced people, help me solve this problem that is exhausting me. How can I enable shell_exec? shell_exec() has been disabled for security reasons, please contact your host provider to enable it. shell_exec is required to enable this system. More on forum.hestiacp.com
🌐 forum.hestiacp.com
1
0
November 18, 2023
shell - php shell_exec() command is not working - Stack Overflow
Are you running php in safe mode? Also read through the comments here us2.php.net/shell_exec as some of them seem helpful. 2013-11-21T16:11:07.85Z+00:00 ... Most web hosting services have disable by default this option and they do not let you enable it.. More on stackoverflow.com
🌐 stackoverflow.com
🌐
PHP
php.net › manual › en › function.shell-exec.php
PHP: shell_exec - Manual
I wanted to run Ghostscript via ImageMagik's "convert" and ended up having to add my path before running the command: <?php $cmd = 'export PATH="/usr/local/bin/"; convert -scale 25%x25% file1.pdf[0] file2.png 2>&1'; echo "<pre>".shell_exec($cmd)."</pre>"; ?> ALSO, note that shell_exec() does not grab STDERR, so use "2>&1" to redirect it to STDOUT and catch it. ... Just a quick reminder for those trying to use shell_exec on a unix-type platform and can't seem to get it to work.
🌐
Ynet Interactive
ynetinteractive.com › blog › How-To-Enable-or-Disable-Shell_exec-in-PHP-17
How To Enable or Disable Shell_exec in PHP
How To Enable or Disable Shell_exec in PHP · 13 Jun · 57157 · First you need to find the location of PHP.ini. You will need to have root access to your server before you can perform the following steps · Type this command in the shell: It should output this text: Open the PHP.ini file and remove ?exec?
🌐
Stack Overflow
stackoverflow.com › questions › 28639918 › allow-php-apache-to-shell-execute-commands-on-ubuntu
Allow PHP/Apache to shell_execute commands on Ubuntu - Stack Overflow
Should work: echo shell_exec("gunzip -c -t $path_to_backup_file 2>&1"); In the above example, a line break at the beginning of the gunzip output seemed to prevent shell_exec printing anything else.
🌐
Namecheap
namecheap.com › support › knowledgebase › article.aspx › 9396 › 2219 › how-to-enable-exec
How to enable exec() - Hosting - Namecheap.com
To enable exec() function, you need to remove it from the following line in your php.ini file: disable_functions = "show_source, system, shell_exec, exec" 1. Open your php.ini and find the following section: 2. Remove exec from the line and click on Save Changes: 3.
Find elsewhere
🌐
Bobcares
bobcares.com › blog › how-to-enable-exec-function-in-php-ini
How to enable exec function in php.ini : Let's figure it out
April 7, 2020 - To enable this function, we login to the server as the root user. Then we open the php.ini file and search for exec function. Usually, this function will be disabled. So, we check the disable_functions directive which appears as, disable_functions ...
Top answer
1 of 2
1

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.

2 of 2
0

Instead of

shell_exec($wkhtmltopdfCommand);

try

$result = passthru($wkhtmltopdfCommand . ' 2>&1');
var_dump($result);

and it should tell you what's wrong.

🌐
Hoststud
hoststud.com › home › resources › others
What is shell exec() function and how to enable or disable it on Linux server? | Web Hosting Forum - Review - Community & Resources
August 7, 2018 - <? php echo shell_exec (“hostname”); ?> In this technique, the administrator don’t want to login to the server through SSH or other means to run shell commands and scripts on the Server. When the above code is executed, the result will be the host name of the server.
🌐
GitHub
gist.github.com › MahbbRah › bd4e7c8905c118dffeacd44934a7c450
Enable exec shell_exec in php · GitHub
Enable exec shell_exec in php. GitHub Gist: instantly share code, notes, and snippets.
🌐
DigitalOcean
digitalocean.com › community › questions › how-to-check-if-the-exec-function-is-enabled-in-my-php-install
How to check if the exec() function is enabled in my PHP install | DigitalOcean
February 20, 2021 - If exec is not listed in the disable_functions line it means that it is enabled. ... If you already have PHP installed on your droplet, you can SSH to it, create a new file, for example test_exec.php like so
🌐
Linux Tip
linuxscrew.com › home › programming › php › php shell_exec function: how to use it [with examples]
PHP shell_exec Function: How to Use It [With Examples]
February 23, 2021 - $fileList = shell_exec('ls -la 2>&1'); echo "<pre>$fileList</pre>"; 2>&1 tells the shell to redirect stderr output to the current stdout – which resolves the issue. To run a command in the background, redirect the output to /dev/null – this sends the output to nowhere (effectively sending it to the abyss), rather than PHP waiting for the response, it will execute the code and resume running PHP immediately – the result from shell_exec will not be waited on, and will not be available to PHP.
🌐
Unix.com
unix.com › unix for beginners q & a
Shell_exec is not working - UNIX for Beginners Q & A - Unix Linux Community
September 20, 2019 - I am trying to execute a command with shell_exec but this command does not work, other commands work <?php $output = shell_exec("tail /var/log/syslog"); echo "<pre>$output</pre>"; ?>