www.webdeveloper.com
Page 2 of 2 FirstFirst 12
Results 16 to 19 of 19

Thread: output shell script output via php and web browser - HELP!

  1. #16
    Join Date
    May 2009
    Posts
    3
    Hello again - I just spent the past hour and a half writing a little iFrame polling script because iFrames are REALLY ugly and they usually end up with scrollbars that you don't want.

    I needed nicely formatted output with no scrollbars.

    Change the iframe code to this:

    Code:
    <iframe id="iframe_source" src="commands.php" style="display: none;" />
    <div id="visual_destination"></div>
    <script>
    // At an interval of 250 milliseconds, update the content of "visual_destination" with the data that is currently loaded in the "iframe_source" element.
    new iFramePoller("iframe_source", "visual_destination", 250);
    </script>

    iframe-poller.js // requires Prototype JS (http://prototypejs.org/)
    Code:
    /**
     * Copyright 2009 Michael White
     * 
     * You may contact me at: michael--at--getsprink--dot--com
     * Website: http://getsprink.com
     * 
     * LICENSE: This code is free for use and modification provided this copyright notice and license remains in tact.
     * This software comes without ANY warranty, expressed or implied. (i.e. - this code may or may not work for you!)
     * 
     * If you do use this code or a modified version of it on a project/website I would like to know! Contact me at the e-mail address listed above.
     * 
     * I do offer paid consultation and assistance services for your JavaScript and PHP needs.
     * 
     * If you would like help implementing or modifying this software for your solution, contact me at michael--at--getsprink--dot--com
     * 
     */
    
    
    // This script is used to poll an iframe on a set interval and update an HTML container element.
    
    // Data is checked each time a content check is made to make sure that the data has actually changed prior to updating the destination element.
    
    // Also, the onload event is listened for on the iFrame and that event triggers the stopPolling() function and no more updates are made after that point.
    
    // It makes sense to set the iframe's display property to "display: none;" so that only the other HTML container element is visible.
    
    // You can configure the interval frequency
    
    var iFramePoller_InstanceStack = {};
    
    var iFramePoller = Class.create({
    	global_config: {
    		trace: false,
    		log: false
    	},
    	source_id: null,
    	dest_id: null,
    	source_el: null,
    	dest_el: null,
    	interval: 250,
    	data_cache: null,
    	poll_timer: null,
    	reference_id: null,
    	initialize: function(iframe_source_id, destination_element_id, interval) {
    		this.source_id = iframe_source_id;
    		this.source_el = $(this.source_id);
    		
    		this.dest_id = destination_element_id;
    		this.dest_el = $(this.dest_id);
    		
    		this.interval = interval ? interval : this.interval;
    		
    		// Generate a random reference ID to persist the scope when using setTimeout
    		this.reference_id = "iFramePoller-instance-id-"+Math.random(30, 1500);
    		
    		this.startPolling();
    		
    		iFramePoller_InstanceStack[this.reference_id] = this;
    	},
    	__trace: function(function_name) {
            if(this.global_config.trace === true) {
                console.log("iFramePoller." + function_name + "()");
            }
        },
        __log: function(message) {
            if(this.global_config.log === true) {
                console.log(message);
            }
        },
        setTimer: function() {
        	// Setup a timer for checking the iFrame content and updating the destination element.
    		this.poll_timer = setTimeout(this.doPoll.bind(this), this.interval);
        },
    	startPolling: function() {
        	this.__trace("startPolling");
    		var ref = this.reference_id;
    		// Setup a listener callback for the onload event of the source iFrame
    		Element.observe(this.source_el, "load", this.stopPolling.bind(this));
    		this.setTimer();
    	},
    	stopPolling: function() {
    		this.__trace("stopPolling");
    		clearTimeout(this.poll_timer);
    		this.updateContent();
    		// Delete the iframe 0.5 seconds after the last content update.
    		setTimeout(this.destroySourceIframe.bind(this), 500);
    	},
    	destroySourceIframe: function() {
    		this.source_el.remove();
    	},
    	doPoll: function() {
    		this.__trace("doPoll");
    		this.updateContent();
    		this.setTimer();
    	},
    	updateContent: function() {
    		this.__trace("updateContent");
    		var doc = null;
    		if(this.source_el.contentDocument) {
                this.__log("Using contentDocument");
                doc = this.source_el.contentDocument;
            }
            /* Bugfixed to work in IE6 */
            else if(iframe.contentWindow.document) {
                this.__log("Using contentWindow.document");
                doc = this.source_el.contentWindow.document;
            }
            else {
                this.__log("Using frame[frame_id].document");
                doc = window.frame[this.source_id].document;
            }
    
            this.dest_el.innerHTML = doc.body.innerHTML;
    	}
    });

  2. #17
    Join Date
    Aug 2013
    Posts
    1

    Smile thank you

    It worked like a dream !!! Thanks
    Quote Originally Posted by mongoose643 View Post
    hey guys, i've wanted to do this in the past but my will power gave out. But this time i was more persistent.

    I tried using the code znupi posted but i couldn't get it to work.

    However, i went back to php.net and really read over the different manual pages on the system(), passthru(), exec(), shell_exec() functions and backticks operator.

    There is a big difference between using the system() or passthru() functions from using any of the others.

    This difference is how the output buffers of the command execution are handled.

    In system() and passthru(), php will attempt to flush the buffers after *every* line of output.

    This means that this code:

    PHP Code:
    system("echo \"starting...\"
    sleep 2
    echo \"done.\""
    ); 
    will be treated just like this code written in only php:

    PHP Code:
    echo "starting...";
    sleep(2);
    echo 
    "done."

    as long as you are not using output buffering on your page (ob_start()) then the effect will be exactly what you are looking for since the buffers will be flushed to the browser after each line of command output.

    But of course there is a caveat!

    It doesn't work with executing custom shell scripts! (well - not without a small workaround)

    the workaround is really simple though. Just use file_get_contents("myscript.sh") to turn the shell script contents into a command string. Insert that command string into your system() command and voila! The output buffers are flushed as expected.

    Note: One thing i did *not* test was the effect of this process on the working directory for the execution of the shell script commands. However, if your shell script relies on a particular working directory then make sure that the working directory is either set inside the shell script itself or that you do a "cd /custom/dir/here" (change directory) command just prior to where you insert the shell script command string.

    Example: (two files: Test.php and test.sh)

    test.php
    PHP Code:
    <?php

    $tmp_file 
    dirname(__file__)."/tmp.txt";
    if(!
    is_file($tmp_file)) {
        
    $fp fopen($tmp_file"w+");
        if(
    $fp) {
            
    fclose($fp);
        }
    }
    echo 
    "<pre>";
    $test_script file_get_contents("test.sh");
    system("echo \"starting...\"
    sleep 2
    echo \"doing more...\"
    "
    .$test_script."
    echo \"done.\""
    );
    echo 
    "</pre>";
    test.sh
    Code:
    echo "running test..."
    
    sleep 1
    
    echo "almost done..."
    
    sleep 1
    
    echo "test complete."

    and for those of you (like me) who are using output buffering on the entire page for whatever reason (templates, caching, error handling) - there is still a little more hacking to do. As long as your output is (x)html then the following solution will work for fully output buffered pages (ob_start()).

    Separate your system() and passthru() calls into a plain php file that just outputs plain text: (obviously make sure that you force some sort of user authentication prior to actually running the commands.php script!)

    commands.php
    PHP Code:
    <?php
    header
    ("content-type: Text/plain");

    $script file_get_contents("script.sh");
    system($script);
    then output html containing an iframe:

    Dostuff.htm
    Code:
    <html>
    <head>
    </head>
    <body>
    <iframe src="commands.php" scrolling="auto"></iframe>
    </body>
    </html>
    good luck!


    ----------------
    michael--at--getsprink--dot--com
    http://getsprink.com/
    http://phpjs.org/

  3. #18
    Join Date
    Mar 2007
    Location
    localhost
    Posts
    2,213
    Usually a shell script on a web host will run in the area of the server that is not accessible to the public side of operations, this in many hosts is a security precaution.

    The host I use has this kind of feature set up.

    On the host I use I have a shell script that runs every hour to scrape a file in the webspace thats public, it is on the shell side a simple test to see if the hour is equal to 1/4 of a 12 hour period.

    If not then operations cease.

    If it is then the shell script calls a PHP script that then does the processing of the data, pushes information in to a datafile and database.

    On the public side of things, the public page reads the file and database, no need to call a shell script web side as the process has been automated to write a data file and push data in to a database that is then made publicly available.

    So you might want to set up a shell that is cronjobbed every few minutes that writes or pushes your data via a PHP script.
    Yes, I know I'm about as subtle as being hit by a bus..(\\.\ Aug08)
    Yep... I say it like I see it, even if it is like a baseball bat in the nutz... (\\.\ Aug08)
    I want to leave this world the same way I came into it, Screaming, Incontinent & No memory!
    I laughed that hard I burst my colostomy bag... (\\.\ May03)
    Life for some is like a car accident... Mine is like a motorway pile up...

    Problems with Vista? :: Getting Cryptic wid it. :: The 'C' word! :: Whois?

  4. #19
    Join Date
    May 2009
    Posts
    3

    Talking You're welcome!

    Quote Originally Posted by nipun1229 View Post
    It worked like a dream !!! Thanks
    Wow - I had completely forgotten that I wrote that up and posted those examples. Kind of cool to see someone is able to make good use of it four years after I wrote it. It certainly helps to vindicate the hours of research I spent figuring it all out.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles