Foros del Web » Programando para Internet » PHP »

Una duda con fgets

Estas en el tema de Una duda con fgets en el foro de PHP en Foros del Web. Tengo un script en donde ustilizo while y fgets para leer una terminal linux que siempre esta enviando informacion por lo tanto el comando fgets ...
  #1 (permalink)  
Antiguo 28/01/2009, 02:24
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Una duda con fgets

Tengo un script en donde ustilizo while y fgets para leer una terminal linux que siempre esta enviando informacion por lo tanto el comando fgets siempre esta enviando la informacion nueva a la pagina web y el while es permanente.

$stdout_stream = ssh2_exec($connection, $ejecutar);

$stderr_stream = ssh2_fetch_stream($stdout_stream, SSH2_STREAM_STDERR);

stream_set_blocking($stdout_stream, true);
stream_set_blocking($stderr_stream, true);


while($line = fgets($stderr_stream)) {
flush();
echo $line."<br />";
}

while($lin2e = fgets($stdout_stream)) {
flush();
echo $line2."<br />";
}

Pero resulta que tengo un problema grande, como los while son permanentes ya que la consola siempre esta enviando informacion nueva al comando fgets, siempre esta ejecutando el primer while que es donde muestra los errores que esta tirando la consola y como es permanente nunca pasa al while que esta debajo que es donde muestra la otra informacion de la consola, lo que necesito es que la persona quee sta ejecutando el script desde su casa pueda ver el contenido de esos dos while a la vez, los errores de la consola y la informacion normal de la consola, finalmente la persona solo se queda biendo todo el tiempo los errores sin ver la informacion principal y necesito que se vean los dos. O tambien si hay una funcion del SSH2 que me permita ver los errores junto con la informacion normal tambien me sirve.

Espero alguien me pueda responder, muchas rgacias.
  #2 (permalink)  
Antiguo 28/01/2009, 02:44
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
De acuerdo Respuesta: Una duda con fgets

2 soluciones:

La fácil: Crear una pagina con 2 iframes y en cada iframe pones un trozo de codigo

La difícil: Crear una pagina donde con peticiones ajax recibes la información de las 2 consultas
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #3 (permalink)  
Antiguo 28/01/2009, 02:58
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

Esas podrian ser las soluciones mas factibles pero hay un problema, para ejecutar la mayor parte del codigo php utilizo variables predefinidas en formularios, y si utilizo iframes en la web o utilizo ajax para llamar script el codigo php no me va a reconocer las variables que se definieron en el formulario.

Gracias.
  #4 (permalink)  
Antiguo 28/01/2009, 03:50
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: Una duda con fgets

¿Tienes algún problema en guardar los datos en variables de sesión?
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #5 (permalink)  
Antiguo 28/01/2009, 12:38
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

No pero si guardo las variabes y luego utilizo el iframe, en el iframe no me reconoce las ariables por que al usar el iframe es como si en ese sector se abriera otro navegador externo,
  #6 (permalink)  
Antiguo 28/01/2009, 14:08
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Una duda con fgets

La unica forma es enviando con dos frames diferentes, ya que aunque usaras AJAX, necesitarias tener los dos procesos en paralelos, y esto por lo que tu mismo especificaste, al tener los dos whiles trabajando nunca se va a pasar al otro while, por lo que este tiene que existir en otro proceso.

Desgracidamente / afortunadamente PHP no soporta threads como Java, por lo que vas a tener que usar la tecnica de dos frames concurrentes.

Saludos
  #7 (permalink)  
Antiguo 28/01/2009, 14:08
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: Una duda con fgets

y que problema le ves para hacerlo mediante ajax?
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #8 (permalink)  
Antiguo 28/01/2009, 14:32
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

@GatorV ¿me puedes dar un ejemplo porfavor? muchas gracias.
  #9 (permalink)  
Antiguo 28/01/2009, 14:44
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Una duda con fgets

Simplemente crea 2 scripts, uno para cada terminal y los linkeas cada uno en su frame.

Saludos
  #10 (permalink)  
Antiguo 28/01/2009, 15:08
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

mmm, esa solucion no me daria el resultado esperado...

si lo hiciera asi tendrian que haber dos formularios apra abrir cada terminal con los iframes y no es la idea, no abra una fucnion del SSH2 que me permita ver las dos informaciones al msimo tiempo? es decir que no las tire separadas con distintos comandos.
  #11 (permalink)  
Antiguo 28/01/2009, 15:27
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Una duda con fgets

Dudo que el problema, sea con ssh2*, el problema en general es que los dos whiles no pueden ser simultaneaos, a lo mejor podrías hacer algo así:
Código php:
Ver original
  1. while(($line = fgets($stderr_stream)) && ($line2 = fgets($stdout_stream))) {
  2.      flush();
  3.      echo $line."<br />";
  4.      echo $line2."<br />";
  5. }

Saludos
  #12 (permalink)  
Antiguo 28/01/2009, 15:39
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

@GatorV mmm, en teoria ese codigo deberia funcionar pero luego en el script solo me muestra parte de $line y parte de $line2 y se pega en los errores nuevamente es bastante raro...

Agradeceria cualquier otra opcion...
  #13 (permalink)  
Antiguo 28/01/2009, 15:40
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
De acuerdo Respuesta: Una duda con fgets

por si a alguien le interesa he creado un script que simula una consola:
Código PHP:
<?php
$host 
'localhost';
$port 22;
$user 'user';
$password 'password';
$conn = @ssh2_connect($host$port);
if(
$conn)
{
    if(@
ssh2_auth_password($conn$user$password))
    {
        if(
$_POST)
        {
            
$command $_POST['command'];    
            
$stream ssh2_exec($conn$command);
            
stream_set_blocking($streamtrue);
            while(
$o fgets($stream))
            {
                echo 
$o."\n";
            }
            exit();
        }
    }    
}
else
{
    echo 
"Conecction failed";
    exit();
}
?>
Código HTML:
<html>
	<head>
		<script type="text/javascript" src="zajax.js"></script>
		<script type="text/javascript">
			function send()
			{
				
				var a = new zajax();
				a.query = "command="+document.getElementById('command').value;
				a.request();
				a.reqComplete = function(t)
				{
					var p = document.getElementById('shell');
					var pre = document.createElement('pre');
					pre.appendChild(document.createTextNode(t));
					p.appendChild(pre);
				};
			}
		</script>
	</head>
	<body>
		<p>
			<label>Command: </label><input id="command" type="text" /><input type="button" value="send" onclick="send()" />
		</p>
		<p id="shell">
		</p>
	</body>
</html> 
zajax.js
Código javascript:
Ver original
  1. /**
  2.  * @author zital
  3.  *
  4.  * zajax: ajax library
  5.  * license: GPL 3.0
  6.  * version: 1.0.1
  7.  */
  8.  
  9. var zajax = function()
  10. {
  11.     this.page; // page to request the petition, default: the same page (window.location)
  12.     this.method; // ajax method: post or get, post by default
  13.     this.charset; // charset utf-8 by default
  14.     this.response; // response method, XML or Text, Text by default
  15.     this.query; // GET or POST query separated by & blank for default
  16.     this.async; // ajax connection method, true by default (firefox needs true to work)
  17.     this.getSeparator; // pagename and parameters separator ? by default
  18.  
  19.     // request public method
  20.     zajax.prototype.request = function()
  21.     {
  22.         var a = new xmlhttp(); // get xmlhttp object
  23.         if(a) // if browser support ajax
  24.         {
  25.             setDefault.call(this); // set default properties
  26.  
  27.             var b = headers(this.method, this.charset); // set get/post different headers
  28.             petitionConstruct.call(this); // construct get/post different properties
  29.  
  30.             this.beforeReq(); // Method to do before all process
  31.  
  32.             a.open(this.method,this.page,this.async); // open ajax petition
  33.             a.setRequestHeader('Content-Type', b); // set headers ALWAYS after OPEN
  34.             a.send(this.query); // send get/post query
  35.             state(this, a); // ajax reponse state
  36.         }
  37.     };
  38.  
  39.     // public methods to redefine: w3schools.com
  40.     zajax.prototype.beforeReq = function(){}; // method to do before all process
  41.     zajax.prototype.reqSetUp = function(){};     // method to do when The request has been set up
  42.     zajax.prototype.reqSend = function(){}; // method to do when The request has been sent
  43.     zajax.prototype.reqInProcess = function(){}; // method to do when The request is in process
  44.     zajax.prototype.reqComplete = function(t){}; // method to do when The request is complete
  45.     zajax.prototype.reqError = function(){};    // method to do when The request return error
  46.  
  47.     // private method to set default properties
  48.     var setDefault = function()
  49.     {
  50.         if(!this.method || this.method.toLowerCase()!='get') this.method='post';
  51.         if(!this.page) this.page=window.location;
  52.         if(this.async!=false) this.async=true;
  53.         if(!this.charset) this.charset='utf-8';
  54.         if(!this.response || this.response.toLowerCase()!='xml') this.response='txt';
  55.         if(!this.query) this.query='';
  56.         if(typeof(this.getSeparator)=='undefined') this.getSeparator='?';
  57.     };
  58.  
  59.     // private method to set get/post headers
  60.     var headers = function(m, c)
  61.     {
  62.         var a = '';
  63.         if(m.toLowerCase()=='post')
  64.             a = a + "application/x-www-form-urlencoded;"; // post Header
  65.         a = a + "charset="+c;
  66.         return a;
  67.     };
  68.  
  69.     // private method set get/post petition properties
  70.     var petitionConstruct = function()
  71.     {
  72.         // DEFAULT POST example page = index.php and query = a=hello, php -> $_POST['hello']
  73.         if(this.method!='post')// GET example page = index.php?a=hello and query = '', php -> $_GET['hello']
  74.         {
  75.             this.page = this.page+this.getSeparator+this.query;
  76.             this.query = '';
  77.         }
  78.     };
  79.    
  80.     // private method to set ajax petition state
  81.     var state = function(t, a)
  82.     {
  83.         if (t.async)
  84.             a.onreadystatechange = function() // get petition changestates
  85.             {
  86.                 switch(a.readyState)
  87.                 {
  88.                     case 1: // if readystate is 1 The request has been set up
  89.                         t.reqSetUp();
  90.                         break;
  91.                     case 2: // if readystate is 2 The request has been sent
  92.                         t.reqSend();
  93.                         break;
  94.                     case 3: // if readystate is 3 The request is in process
  95.                         t.reqInProcess();
  96.                         break;
  97.                     case 4: // if readystate is 4 the request is complete
  98.                         reqResponse.call(t, a);
  99.                         break;
  100.                 }
  101.             };
  102.         else
  103.             reqResponse.call(t, a);
  104.     };
  105.    
  106.     // private method to get ajax petition response
  107.     var reqResponse = function(a)
  108.     {
  109.         if(a.status==200) // if status is 200 petition OK      
  110.             if (this.response == 'txt') // if get plain text
  111.                 this.reqComplete(a.responseText); // execute complete method
  112.             else // else get XML
  113.                 this.reqComplete(a.responseXML); // execute complete method    
  114.         else
  115.             this.reqError(); // if error occurred execute error method
  116.     };
  117.    
  118.     // private method get xmlhttp object
  119.     var xmlhttp = function()
  120.     {
  121.         var a;try{a = new XMLHttpRequest();}
  122.         catch(e){try{a = new ActiveXObject('Msxml2.XMLHTTP');}
  123.         catch(e){try{a = new ActiveXObject('Microsoft.XMLHTTP');}
  124.         catch(e){alert('Your browser doesn\'t support ajax');a=false;}
  125.         }}return a;
  126.     };
  127. };
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #14 (permalink)  
Antiguo 28/01/2009, 15:58
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

Eres un genio ZiTaL ese script funciona de maravilla estoy seguro que lo usare, no se si pdorias hacer que tambien muestre los errores de la consola por que apesar de que funciona de maravilla no muestra los errores, muchas gracias amigo.
  #15 (permalink)  
Antiguo 28/01/2009, 16:16
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: Una duda con fgets

A ver asi:
Código PHP:
<?php
$host 
'localhost';
$port 22;
$user 'user';
$password 'password';

$conn = @ssh2_connect($host$port);
if(
$conn)
{
    if(@
ssh2_auth_password($conn$user$password))
    {
        if(
$_POST)
        {
            
$command $_POST['command'];    
            
$stream = @ssh2_exec($conn$command);
            
stream_set_blocking($streamtrue);

            
$result '';
            while(
$o fgets($stream))
            {
                
$result.= $o."\n";
            }

            if(!empty(
$result))
            {
                echo 
$result;
            }
            else
            {
                echo 
"The command return an error";
            }
            exit();
        }
    }
    else
    {
        echo 
"Authentication failed";
        exit();
    }
    
}
else
{
    echo 
"Conecction failed";
    exit();
}
?>
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #16 (permalink)  
Antiguo 28/01/2009, 16:27
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Una duda con fgets

Mmmm... no funciona, sigue sin mostrar los errores.
  #17 (permalink)  
Antiguo 28/01/2009, 16:29
Avatar de ZiTAL  
Fecha de Ingreso: marzo-2004
Ubicación: Bermio (Bizkaia)
Mensajes: 1.545
Antigüedad: 20 años, 1 mes
Puntos: 62
Respuesta: Una duda con fgets

ese comando si da fallo no lo devuelve solo respuesta en blanco. Por eso si es blanco pongo el mensaje de que el comando ha fallado. No se si se podrá hacer de otra forma.
__________________
http://zital.no-ip.org
____________________

Euskerie ahuen eta bijotzan
  #18 (permalink)  
Antiguo 28/01/2009, 16:36
 
Fecha de Ingreso: enero-2009
Mensajes: 19
Antigüedad: 15 años, 2 meses
Puntos: 0
Si eso me di cuenta, pero necesito que me de el error en concreto...

Gracias.

Disculpen por el repost, lo que pasa en concreto es lo siguente:

El while lee $line y despues $line2, pero si while lee $line2 que es de errores y no da resultado se queda esperando un resultado entonces no vuelve a leer $line que es donde debe dar lo que no es errores, tienen alguna idea de como solucionar esto?

Gracias

Nadie tiene una posible solucion?

Última edición por GatorV; 28/01/2009 a las 22:38
  #19 (permalink)  
Antiguo 28/01/2009, 22:38
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Una duda con fgets

Como te comento, el problema viene en la concurrencia, la unica y repito UNICA forma es usando dos scripts por separado y usar dos frames o AJAX como el código de Zital.

PHP no soporta Threads para que puedas tener la concurrencia que necesitas.

Saludos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 18:14.