Bash script execution from php and instant output back to web page

I have a set of bash and perl scripts for

  • create the directory structure needed for deployment in linux box
  • (optional) export code from svn
  • create package from this source

This works well with the terminal. Now my client is requesting a web interface for this process.

for example, the “Create a new package” button on a specific page is called up one after another above the steps and returns the result to the user as a script echos, and not when all scripts are executed.

Is it possible to send instant output from a bash script to a web page or a PHP script that called it through the program's execution functions (system, exec, passthru ... or something else that corresponds to this process thread)?

What is elegant, why do this?

What precautions should I take when doing such a thing (if possible)?

Edit After some searching, I found part of the solution, but still did not work:

$cmd = 'cat ./password.txt|sudo -S ./setup.sh '; $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a pipe that the child will read from ); flush(); $process = proc_open($cmd, $descriptorspec, $pipes, './', array()); echo "<pre>"; if (is_resource($process)) { while ($s = fgets($pipes[1])) { print "Message:".$s; flush(); } while ($s = fgets($pipes[2])) { print "Error:".$s; flush(); } } echo "</pre>"; 

output: (web page)

 Error:WARNING: Improper use of the sudo command could lead to data loss Error:or the deletion of important system files. Please double-check your Error:typing when using sudo. Type "man sudo" for more information. Error: Error:To proceed, enter your password, or type Ctrl-C to abort. Error: Error:Password: Error:Sorry, try again. Error:Password: Error:Sorry, try again. Error:Password: Error:Sorry, try again. Error:sudo: 3 incorrect password attempts** 

The first release I have now is to pass sudo passoword

help me please!

+4
source share
6 answers

I would use a kind of lead / follower project. Your perl / bash script will be subordinate, just doing the job (packing, compiling, exporting the code or so on) and submitting a log entry.

The wizard will be your php process. Thus, the principle is as follows: the master and slave share the communication channel and report asynchronously from this channel.

You can imagine such a database as:

 create table tasks ( id INT primary key, status INT, argument VARCHAR(100)); 

On the php page, you should select the user and filter :

 switch ($_GET['action']) { case 'export': $argument = sanitize($_GET['arg']); add_task('export', $argument); break; case '...': // ... } 

and the add_task function might look something like this:

 function add_task($action, $arg) { return $db->add('tasks', array($action, NEW_TASK, $arg); } 

Slaves can run through a cron job and query the database, ensuring the task is completed.

Pros are:

  • independent systems facilitate evolution.
  • If the client disconnects, work will never be lost.
  • easier to protect

Ends:

  • a little harder at the beginning.
  • less reactive due to the interrogation time of working slaves (for example, if they work every 5 minutes)
  • less result than direct command output

Please note that you can implement triggers like xml-rpc to start slaves, rather than using a messaging system.

+4
source

The easiest way is to use shell_exec for your purpose. It executes the command through the shell and returns the full output as a string, so you can display it on your website.

If this is not suitable for your purpose, because maybe you want to get answers waiting for the command to complete, check out the other available program execution functions in php (hint: there are some good comments on the manual pages).

Keep in mind that when invoking command line scripts, this generated output will have the file owner, group and permissions of your web server (pe wwwrun or something else). If parts of your deployment require separate owner, group and / or file rights, you must manually install them either in your scripts or after calling shell_exec ( chmod , chown and chgrp can deal with this in php).

Security: Many web applications place this feature in a separate installation directory and ask you to remove this directory after installation. I even remember how some of them shouted at admins who were persistent enough, unless they were removed. This is an easy way to prevent the wrong hands from using this script at the wrong time. If your application may be needed after installation, you should place it in an area in which only authorized users are available (pe administration area or something similar).

+1
source

You can use the Comet web application model to update the results page in real time.

For the sudo problem, as a quick and dirty solution, I would use a limited set of commands that the web server can execute without a password. Example (add /etc/sudoers ):

apache ALL=(ALL) NOPASSWD: /sbin/service myproject *

which will allow apache to run /sbin/service myproject stop , /sbin/service myproject start , etc.

Take a look at Jenkins , it makes the web part beautiful, you will need to add your scripts to the assembly.

A better solution would be, as suggested by Aif , to separate the logic. One process is a daemon waiting for tasks and a web application that visualizes the results.

+1
source

Always use escapeshellarg and escapeshellcmd when executing system commands through PHP for security. It would also be suggested that the user in the chroot'd directory be as limited as possible.

0
source

It seems you have solved the problem of getting stdout and stdin to output to your web page using proc_open . Now the problem is script execution via sudo.

From a security point of view, having a PHP application will run the script as root (via sudo), making me cringe. Having the root password in password.txt is a pretty serious security hole.

What would I do (if possible), make all the necessary changes so that setup.sh can be started by the unix user who runs Apache. (I assume that you are using PHP with Apache.) If setup.sh is run by a web server, it should be able to run it without resorting to sudo.

If you really need to run the script as another user, you can check out suPHP , which is designed to run PHP scripts as a non-standard user.

0
source

Grant sudo automatic rights to a specific user using the NOPASSWD / etc / sudoers option, then run the command with the prefix sudo -u THE_SUDO_USER so that the command sudo -u THE_SUDO_USER as that user. This prevents a security hole for granting sudo user rights to all Apache users, but also allows you to execute sudo on a script from within apache.

0
source

All Articles