GithubHelp home page GithubHelp logo

interexec's Introduction

This project is not maintained anymore, please use symfony/process instead.


InterExec

Copyright 2012 Christian Sciberras & Contributors

No Specific Licensing (do whatever you want with it)

Description

PHP command execution on steroids (aka interactively).

A PHP class for running programs through PHP, (uses proc_open()), interactively, that is giving a chance to your script to respond to input requests accordingly.

Example

Assuming we have the following batch script:

@ECHO OFF
SET /p name=Enter your name: 
ECHO Hello, %name%!
PAUSE

One can interact with this batch script as follows:

$exec = new InterExec('test.bat');

$exec->on('start', function(){
	echo 'Start<br/>';
});

$exec->on('output', function($exec, $data){
	echo '&gt; '.$data.'<br/>';
});

$exec->on('input', function($exec, $last){
	$data = PHP_EOL; // default input, to unblock stream
	if($last == 'Enter your name: ')
		$data = 'John Doe'.PHP_EOL;
	echo '&lt; '.$data.'<br/>'; 
	return $data;
});

$exec->on('stop', function(){
	echo 'Stop<br/>';
});

$exec->run();

The above would result in the following page:

Start
> Enter your name: 
< John Doe
> Hello, John Doe!
> Press any key to continue...
< 
Stop

Documentation

Properties

string $command_to_run

The command to run.

array|null $environment_vars

Environment variables (null to use existing variables).

integer $timeout

Time, in seconds, after which command is forcefully aborted.

string $stdout

All of the program's standard output till now.

string $stderr

All of the program's error output till now.

integer $return

Program's exit code (obviously only set after program quits).

float $time_start

Timestamp of when execution started.

float $time_taken

The time taken for the program to run and close.

boolean $fix_windows_path

If enabled, fixes a problem with popen not allow spaces inside program path (even when quoted).

float $tick_interval

Interval between ticks, in seconds (a value of zero disables interval).

resource $process_handle

Resource handle for currently running command process (or null if none running).

integer $data_buffer_size

Size of buffer for reading from pipes.

string $pipeType

Type of the pipe, InterExec::PIPE_TYPE_DEFAULT or InterExec::PIPE_TYPE_PTY

Methods

__construct($command_to_run [, $environment_vars])

Constructs new execution instance. string $command_to_run The command line to execute. array $environment_vars (Optional) Environment variables.

on($event, $callback)

Calls $callback when an event is triggered. string $event Name of event. callable $callback The callback to call.

is_running()

Returns whether process is currently running or not.

run()

Runs the specified command.

Events

  • start - Triggered when program starts.
  • stop - Triggered when program ends.
  • tick - Triggered on each execution step (see interval property).
  • input($last):$data - Called when program is requesting input. Argument $last contains last output buffer. Callback should return $data to be sent to program.
  • output($data) - Called when program sent some output. Argument $data contains the standard output fragment.
  • error($data) - Called when program signals erroneous state. Argument $data contains the standard error fragment.

All callbacks will receive the command object that triggered the event, as first parameter (as a solution to unavailability of $this in PHP object callbacks).

interexec's People

Contributors

daverandom avatar konsultaner avatar uuf6429 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

interexec's Issues

Add logging system

I think it's probably useful to have a debugging system (that is disabled by default).

I suppose this might be a problem with the core code (execution) loop is not really testable. :(

Can't wait for output before inputting something else

The interactive session should be this:

name
= my thing
protocol_version
= 2

etc. I need to wait for a line starting with = before inputting the next thing, but it seems like this script just spam inputs all the strings and there is no way to tell it to chill out (since PHP_EOL actually results in an empty command error in my script)

run() method is tooo big

Split that big method into sub-(protected?)methods.

This should also make the class much more testable.

Offload event system to an "Event" class

I'm still not sold to this idea. I mean, adding an event class to this library seems way out of scope.

Or maybe an InterExecEvents interface? At least we'd get a real list of supported events (as method names).

...more discussion on this to follow...

Main loop too slow

I was testing your script with a bat file on windows that just outputted some strings. I found out that only putting the tick-time to 0 would output nerly all lines I echoed. The problem ist that php loops a lot slower then some echos in a bat file. The main loop looses output information when iterating. I tested the same bat-file with thise lines of code and it worked well:

@ECHO off
echo hello & echo.world
ECHO "TEST"
ECHO "Line2"
ECHO "%0"
ECHO "%1"
ECHO "%2"
<?php
$cmd = "test\\Mock\\wlanCallCommandMock param1 2";

$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 write to
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo "<pre>";
if (is_resource($process)) {
    $w = array($pipes[0]);
    $r = array($pipes[1],$pipes[2]);
    $e = null;
    $stat = proc_get_status($process);
    // loop on the is_runnning method from InterExec
    while (!(!$stat['running'] || $stat['signaled'] || $stat['stopped'])) {
        $stat = proc_get_status($process);
        var_dump(stream_select($r,$w,$e, null/*, 25000*/));
        print fgets($pipes[1]);
        flush();
    }
}
echo "</pre>";

Reading from STDERR disabled

Had to disable reading from STDERR since it was causing a script block, for some reason.

Also, unblock pipes does not seem to do any difference.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.