Test Foro de elhacker.net SMF 2.1

Programación => Desarrollo Web => PHP => Mensaje iniciado por: agus0 en 17 Marzo 2015, 15:04 PM

Título: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: agus0 en 17 Marzo 2015, 15:04 PM
Hola muchachos... le cuento que tengo una pequeña duda... tengo un Servidor con Ubuntu y PHP 5.6.3 y me gustaría invocar desde PHP a un programa que corre "en modo terminal" y que en algún otro momento pueda enviarle la orden de finalizar el programa...
por si no me explique bien... lo que me gustaría hacer es llamar a que se ejecute un programa desde php, y desde php mas adelante poder enviarle instrucciones al programa... como por ejemplo "stop" y la verdad es que no tengo idea de por donde empezar...
si no fui claro con lo que dije intentare explicarlo de nuevo.

Gracias
Saludos.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 17 Marzo 2015, 16:00 PM
¿Enviar instrucciones? ¿El programa funciona de forma interactiva? Puedes usar 'kill' con shell_exec para matar el proceso.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: agus0 en 17 Marzo 2015, 16:04 PM
Claro. por ejemplo es como el servicio de apache. "apache start", "apache restart" "apache stop"... eso me gustaría poder "controlar"
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 17 Marzo 2015, 16:15 PM
Cita de: agus0 en 17 Marzo 2015, 16:04 PM
Claro. por ejemplo es como el servicio de apache. "apache start", "apache restart" "apache stop"... eso me gustaría poder "controlar"

¿Tienes otro servidor web que esta usando PHP para iniciar el proceso de apache? Ese servidor web debe tener permisos de root para poder iniciar apache al menos bajo el puerto 80. Si es el mismo servidor apache que esta corriendo bajo el mismo puerto solo podrias usar apache stop y para eso tambien necesitas permisos root.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: agus0 en 17 Marzo 2015, 16:24 PM
Di apache como ejemplo pero es otro programa, el problema y la diferencia con apache es que usando shel_exec() es como si se cerrara "terminal" en la que estoy ejecutando el  programa
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 17 Marzo 2015, 16:34 PM
Cita de: agus0 en 17 Marzo 2015, 16:24 PM
Di apache como ejemplo pero es otro programa, el problema y la diferencia con apache es que usando shel_exec() es como si se cerrara "terminal" en la que estoy ejecutando el  programa

¿Cerrara "terminal"?

Si es un script que solo inicia y detiene un programa en el background entonces con shell_exec te basta. Si es un proceso que continua ejecutandose y no regresa un valor necesitas enviarlo al background:

Código (php) [Seleccionar]

shell_exec(.'/server &>/dev/null &')
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: agus0 en 18 Marzo 2015, 12:54 PM
Cita de: MinusFour en 17 Marzo 2015, 16:34 PM
¿Cerrara "terminal"?

Si es un script que solo inicia y detiene un programa en el background entonces con shell_exec te basta. Si es un proceso que continua ejecutandose y no regresa un valor necesitas enviarlo al background:

Código (php) [Seleccionar]

shell_exec(.'/server &>/dev/null &')


A lo que me refiero con "Cerrar el terminal" es que, la funcion de php "shell_exec()" se comporta como si cada vez que se termina la instrucción la terminal se finalizara (exit), es decir si yo uso
Código (php) [Seleccionar]

<?php
  shel_exec
('cd /home/unacarpeta');
  echo(
shel_exec('ls'));
?>


esto no me muestra el contenido de la carpeta "/home/unacarpeta" sino que muestra el contenido de la carpeta donde se encuentre el archivo php que invoca la función shel_exec(), ahora para motrar el contenido en "/home/unacarpeta" yo tendría que hacer todo en una misma linea usando "&&"




se me ocurrió un ejemplo mas concreto que es casi justo lo que busco...

ejemplo tengo en mi servidor el servicio de "Minecraft" y para iniciarlo tengo que ejecutar el programa Java
Código (bash) [Seleccionar]
java -Xmx2048M -Xms1024M -jar server_minecraft.jar nogui

ahora bien, como puedo invocar a este programa y que no se cierre desde php y en el caso de que mas adelante lo quiera cerrar enviándole la instrucción "stop" como podría hacerlo.
Saludos

Mod: No hacer doble post.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 18 Marzo 2015, 16:44 PM
Cita de: agus0 en 18 Marzo 2015, 12:54 PM
A lo que me refiero con "Cerrar el terminal" es que, la funcion de php "shell_exec()" se comporta como si cada vez que se termina la instrucción la terminal se finalizara (exit), es decir si yo uso
Código (php) [Seleccionar]

<?php
  shel_exec
('cd /home/unacarpeta');
  echo(
shel_exec('ls'));
?>


esto no me muestra el contenido de la carpeta "/home/unacarpeta" sino que muestra el contenido de la carpeta donde se encuentre el archivo php que invoca la función shel_exec(), ahora para motrar el contenido en "/home/unacarpeta" yo tendría que hacer todo en una misma linea usando "&&"




se me ocurrió un ejemplo mas concreto que es casi justo lo que busco...

ejemplo tengo en mi servidor el servicio de "Minecraft" y para iniciarlo tengo que ejecutar el programa Java
Código (bash) [Seleccionar]
java -Xmx2048M -Xms1024M -jar server_minecraft.jar nogui

ahora bien, como puedo invocar a este programa y que no se cierre desde php y en el caso de que mas adelante lo quiera cerrar enviándole la instrucción "stop" como podría hacerlo.
Saludos

Mod: No hacer doble post.

No necesitas hacer un cambio de directorio para usar ls.

Código (bash) [Seleccionar]

ls /home/unacarpeta


En cuanto a tu server de Minecraft, si al iniciar el server no retorna un valor y sigue corriendo el proceso en el foreground tu shell exec se queda colgado, porque sigue esperando una respuesta del comando. Es por eso que tienes que enviarlo al background.

En cuanto a enviar "stop" no se que comando utilices para eso.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: agus0 en 18 Marzo 2015, 16:47 PM
Cita de: MinusFour en 18 Marzo 2015, 16:44 PM
No necesitas hacer un cambio de directorio para usar ls.

Código (bash) [Seleccionar]

ls /home/unacarpeta


En cuanto a tu server de Minecraft, si al iniciar el server no retorna un valor y sigue corriendo el proceso en el foreground tu shell exec se queda colgado, porque sigue esperando una respuesta del comando. Es por eso que tienes que enviarlo al background.

En cuanto a enviar "stop" no se que comando utilices para eso.

si lo de hacerlo en una sola linea lo se, pero lo di a modo de ejemplo...

En el caso del Servidor. tendria que "retomar" esa aplicación que quedo BackGround y enviar la instrucción "stop" ¿es esto posible?




Cita de: MinusFour en 17 Marzo 2015, 16:34 PM
¿Cerrara "terminal"?

Si es un script que solo inicia y detiene un programa en el background entonces con shell_exec te basta. Si es un proceso que continua ejecutandose y no regresa un valor necesitas enviarlo al background:

Código (php) [Seleccionar]

shell_exec(.'/server &>/dev/null &')


otra cosa y perdón por la ignorancia pero me explicas un poco mas...

Para que sirve el "." antes del apostrofo, y para que es el "&>" y el "&" del final. Gracias!

Mod: No hacer doble post.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 18 Marzo 2015, 17:37 PM
Cita de: agus0 en 18 Marzo 2015, 16:47 PM
si lo de hacerlo en una sola linea lo se, pero lo di a modo de ejemplo...

En el caso del Servidor. tendria que "retomar" esa aplicación que quedo BackGround y enviar la instrucción "stop" ¿es esto posible?

shell_exec() no es una terminal interactiva. Si por ejemplo, el programa espera que escribas en la terminal: "stop", no lo vas a poder hacer atraves de shell_exec(). Lo que si puedes hacer es enviar la señal SIGTERM a tu proceso de java por medio de kill. En ese caso no importa si esta en el foreground o background, la aplicacion termina.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: Pablo Videla en 19 Marzo 2015, 14:31 PM
Esto te ayudará.

Código (php) [Seleccionar]
<?php
/* An easy way to keep in track of external processes.
* Ever wanted to execute a process in php, but you still wanted to have somewhat controll of the process ? Well.. This is a way of doing it.
* @compability: Linux only. (Windows does not work).
* @author: Peec
*/
class Proceso{
    private 
$pid;
    private 
$command;

    public function 
__construct($cl=false){
        if (
$cl != false){
            
$this->command $cl;
            
$this->runCom();
        }
    }
    private function 
runCom(){
        
$command 'nohup '.$this->command.' > /dev/null 2>&1 & echo $!';
        
exec($command ,$op);
        
$this->pid = (int)$op[0];
    }

    public function 
setPid($pid){
        
$this->pid $pid;
    }

    public function 
getPid(){
        return 
$this->pid;
    }

    public function 
status(){
        
$command 'ps -p '.$this->pid;
        
exec($command,$op);
        if (!isset(
$op[1]))return false;
        else return 
true;
    }

    public function 
start(){
        if (
$this->command != '')$this->runCom();
        else return 
true;
    }

    public function 
stop(){
        
$command 'kill '.$this->pid;
        
exec($command);
        if (
$this->status() == false)return true;
        else return 
false;
    }
}
?>


ejemplo de prueba

Código (php) [Seleccionar]
 $programa = "/usr/bin/perl script.pl parametros";
            $proceso = new Proceso($programa);


Esperar a que termine por si solo
Código (php) [Seleccionar]

//proceso ejecutando
while($proceso->status()){
           
       }
//proceso finalizado.

Puedes pararlo con los metodos de la clase, saludos.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: agus0 en 24 Marzo 2015, 16:30 PM
Cita de: DonVidela en 19 Marzo 2015, 14:31 PM
Esto te ayudará.

Muchas Gracias... pero no entendí bien como usar esta Clase
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 24 Marzo 2015, 16:56 PM
Cita de: agus0 en 24 Marzo 2015, 16:30 PM
Muchas Gracias... pero no entendí bien como usar esta Clase

Solo es cuestion de pasarle el comando al constructor y de ahi iniciar o detener el proceso. Sin embargo, la clase de la forma en la que esta escrita, no puede detener el proceso entre peticiones. Tendrias que persistir la ID del proceso de alguna forma. Realmente la idea es la misma que comentaba, necesitas usar kill para enviar SIGTERM a tu proceso corriendo.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: Pablo Videla en 24 Marzo 2015, 17:04 PM
Cita de: MinusFour en 24 Marzo 2015, 16:56 PM
Solo es cuestion de pasarle el comando al constructor y de ahi iniciar o detener el proceso. Sin embargo, la clase de la forma en la que esta escrita, no puede detener el proceso entre peticiones. Tendrias que persistir la ID del proceso de alguna forma. Realmente la idea es la misma que comentaba, necesitas usar kill para enviar SIGTERM a tu proceso corriendo.

No sería buena idea mantener identificada por session la ID del proceso y matarla cuando el quiera? Es cosa de modificar la clase.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: MinusFour en 24 Marzo 2015, 17:30 PM
Yo preferiria guardar el proceso en una base de datos o un archivo. Pierdes mucho control sobre la PID si usas sessiones, porque las sessiones pueden expirar, son diferentes para cada usuario/navegador, etc.
Título: Re: [Ayuda] shell_exec y como Correr un programa en segundo plano
Publicado por: Pablo Videla en 24 Marzo 2015, 19:36 PM
Cita de: MinusFour en 24 Marzo 2015, 17:30 PM
Yo preferiria guardar el proceso en una base de datos o un archivo. Pierdes mucho control sobre la PID si usas sessiones, porque las sessiones pueden expirar, son diferentes para cada usuario/navegador, etc.

Todo depende de lo que el necesite hacer exactamente.