30

I have a script in /var/www/myscript.sh which creates folders and runs the command svn update for my projects. I need to execute this script by calling it in a PHP file in the browser (i.e. Localhost/test.php). I tried using functions shell_exec() and exec() but those did not work. I ran my shell script in terminal with su www-data && ./myscript.sh and it worked. What else am I missing?

<?php
$output = shell_exec("./myscript.sh");
?>

Update 5/4/2011:

I added www-data ALL=(ALL) NOPASSWD:ALL to /etc/sudoers and it works, but this is very insecure. Is there another way to do this?

4
  • 5
    Can you define "did not work"? Also, try shell_exec("sh ./myscript.sh"); Commented May 4, 2011 at 11:31
  • Possible dupe of stackoverflow.com/questions/5311384/… which was solved as a permission problem. Is yours a path problem (since you've successfully executed it as the apache user)? Commented May 4, 2011 at 11:33
  • When the file is called via browser it runs normal but on the backend the script was not executed Commented May 4, 2011 at 11:49
  • 2
    I added www-data ALL=(ALL) NOPASSWD:ALL to /etc/sudoers and it worked Commented May 4, 2011 at 12:51

4 Answers 4

12

Several possibilities:

  • You have safe mode enabled. That way, only exec() is working, and then only on executables in safe_mode_exec_dir
  • exec and shell_exec are disabled in php.ini
  • The path to the executable is wrong. If the script is in the same directory as the php file, try exec(dirname(__FILE__) . '/myscript.sh');
Sign up to request clarification or add additional context in comments.

Comments

8

You might have disabled the exec privileges, most of the LAMP packages have those disabled. Check your php.ini for this line:

disable_functions = exec

And remove the exec, shell_exec entries if there are there.

Good Luck!

4 Comments

It might also be wise for OP to check rwx permissions in the directory they're attempting to execute from.
If it was disabled PHP would throw a very specific error explaining it which should be easily fixable, don't know if it would be this!
I have added the disable_functions = exec to php.ini still not working and myscript.sh also has 777 permision
@Rakesh Gabriel said remove it, not add it.
6

Residuum did provide a correct answer to how you should get shell exec to find your script, but in regards to security, there are a couple of points.

I would imagine you don't want your shell script to be in your web root, as it would be visible to anyone with web access to your server.

I would recommend moving the shell script to outside of the webroot

    <?php
      $tempFolder = '/tmp';
      $webRootFolder = '/var/www';
      $scriptName = 'myscript.sh';
      $moveCommand = "mv $webRootFolder/$scriptName $tempFolder/$scriptName";
      $output = shell_exec($moveCommand);
    ?>

In regards to the:

i added www-data ALL=(ALL) NOPASSWD:ALL to /etc/sudoers works

You can modify this to only cover the specific commands in your script which require sudo. Otherwise, if none of the commands in your sh script require sudo to execute, you don't need to do this at all anyway.

Try running the script as the apache user (use the su command to switch to the apache user) and if you are not prompted for sudo or given permission denied, etc, it'll be fine.

ie:

sudo su apache (or www-data)
cd /var/www
sh ./myscript

Also... what brought me here was that I wanted to run a multi line shell script using commands that are dynamically generated. I wanted all of my commands to run in the same shell, which won't happen using multiple calls to shell_exec(). The answer to that one is to do it like Jenkins - create your dynamically generated multi line of commands, put it in a variable, save it to a file in a temp folder, execute that file (using shell_exec in() php as Jenkins is Java), then do whatever you want with the output, and delete the temp file

... voila

Comments

2

If you are having a small script that you need to run (I simply needed to copy a file), I found it much easier to call the commands on the PHP script by calling

exec("sudo cp /tmp/testfile1 /var/www/html/testfile2");

and enabling such transaction by editing (or rather adding) a permitting line to the sudoers by first calling sudo visudo and adding the following line to the very end of it

www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/testfile1 /var/www/html/testfile2

All I wanted to do was to copy a file and I have been having problems with doing so because of the root password problem, and as you mentioned I did NOT want to expose the system to have no password for all root transactions.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.