Ejecutar servidor/servicio en segundo plano

EnZo

Buenas, he programado un servidor de sockets en php para la comunicacion de mi nuevo juego (conkis).
El caso es que soy un cazurro con linux y necesito varias cosas para que el servidor marche.

Tengo un dedicado al que me conecto por telnet para ejecutar el servidor. Necesitaría varias cosas que no se si son posibles:

1º Ejecutar el script en segundo plano, de manera que cuando cierre putty el script siga funcionando. Que funcione como un servicio permanente de mi dedicado.

2º Que todo lo que se imprima por pantalla lo escriba en un fichero log fisico. (Esto creo que sé hacerlo)

3º Esto ya es un poco por capricho, y es que en caso de que se caiga el dedicado por la razón que sea. Que cuando arranque ejecute el comando de 1 y 2. Esto es para no tener que preocuparme de tener que ejecutarlo manualmente.

Gracias de antemano :)

Poisonous

Creo que el 1º y el 3º puedes abordarlos convirtiendo tu script en un demonio

1 respuesta
elkaoD

Y el 2º redirigiendo STDOUT a cualquier archivo.

1 respuesta
neil90

comando &> "nombre de fichero de salida.txt" &

Te recomendaría que utilizases Python antes que PHP para escribir un servidor.

1 respuesta
EnZo

#2 Como harias eso?

#3 Ok, es como suponia. Ty.

#4 Phyton no es mucho mas rapido que php, aunque no sé si estará mas optimizado para sockets que php. En caso de migrar migraria a node.js. Pero el core del servidor lo hice el año pasado y no me sobra el tiempo :(

En cuanto al comando que me has puesto, yo ponia >>. Pero acabo de ver que con &> crea un fichero nuevo en vez de escribir sobre el que ya hubiese. Algo nuevo que sé :)

Tengo un problema con el primer paso. He probado:

php myserverPERFORMANCE.php

php myserverPERFORMANCE.php &

El primero funciona perfectamente, pero no en segundo plano. El segundo, es como si dejase el proceso ejecutandose, pero realmente no está ejecutando php porque no hace nada. El cliente no se conecta y no me saca nada en output.log

php myserverPERFORMANCE.php &> output.log &

Que hago mal?

neil90

No se muy bien como va PHP como standalone, de todos modos, investiga php-cli.

Te sugería Python porque PHP está orientado a ser un CGI, mientras que Python es más de uso general. Como han dicho también, quizá te resulte más fácil programarlo como un daemon y así no andas complicándote con redirecciones y demás.

EnZo

Vale, ya he solucionado el punto 1. Resulta que hay que hacer una especie de puente. Es decir, si mi servidor se llama myserverPERFORMANCE.php he de crear otro script que ejecute myserverPER..

#!/usr/bin/php -q
<?php
echo '#' . exec('php myserverPERFORMANCE.php >> output.log & echo $!') . "\n";
?>

exec ejecutara el comando linux. He optado por >> por si tuviera que volver a arrancarlo que no se pierda lo que ya estuviese logeado. Con & se queda en segundo plano como dijisteis, y echo $! sirve para que devuelva el id del proceso.

Para matar el proceso:
kill XXXX

Si has cerrado la consola y no recuerdas el id del proceso escribe:
ps aux | grep php

Lo pongo por si alguien lo necesita alguna vez :P

Y ahora mismo estoy atascado en el paso 3. He creado un archivo en /etc/init.d/miautorun

#!/bin/sh
/usr/bin/php /path/run

Si escribo sh miautorun. Pero no lo ejecuta cuando reinicio el dedicado.
Alguna sugerencia?

LOc0

http://www.cyberciti.biz/tips/linux-write-sys-v-init-script-to-start-stop-service.html

Salu2 ;)

1 respuesta
PandragoQ

nohup es tu amigo....

$ nohup ./script &

Y toda la salida de STDOUT estara en el archivo nohup.out

#10 man nohup

Basicamente, sirve para lanzar un script inmune a la senyal SIGHUP, y se usa normalmente para deslinkar scripts del terminal donde se lancen.

Otra opcion, si quieres en algun momento lanzar un script que pueda ser interactivo en algun momento, es usar "screen".

1 respuesta
EnZo

Nada, no me rula.

#8 Lo que comentas es lo que quiero hacer pero mas sofisticado. Para hacer lo que comentas primero tengo que saber hacer el basico xD

#9 Para que sirve el comando nohup?

Es que no entiendo como funciona la carpeta init.d

Hay una gran cantidad de archivos dentro que servirán para lo mismo.

Yo pruebo estos dos comandos:

autorun

-bash: autorun: command not found

sh autorun

El segundo lo ejecuta bien el servidor. Entonces linux cuando arranca como sabe que tiene que escribir #sh autorun en vez de autorun?
Todo esto suponiendo que en cuanto arranca lee todos los ficheros de init.d y los ejecuta. Por que mi otra teoria es que existe otro archivo que dice que ficheros tiene que lanzar de ese directorio.

Que creeis que puede ser?

1 respuesta
LOc0

Se me pasaron dos cosas.

1º) El script de /etc/init.d/mi_script hazlo ejecutable con

#chmod 755 /etc/init.d/mi_script

2º) Para que se cargue al arrancar tienes que crear los enlaces simbólicos en /etc/rcX.d/ hacia /etc/init.d/my_script

Si estás en Debian lo haces con el comando

#update-rc.d my_script defaults

http://www.debuntu.org/how-to-manage-services-with-update-rc.d

Si no estás en Debian lo tendrás que hacer a "mano" o googlear.

Salu2 ;)

1 respuesta
EnZo

#11

En cuanto al primer paso ya lo hice en su momendo pero como cmod +x. El caso es que no lo convierte en ejecutable de ninguna de las dos maneras lo convierte en ejecutable. Tambien he probado ha cambiar #!/bin/bash por #!/bin/sh. Pero nada, siempre lo mismo
-bash: autorun: command not found

El segundo no entiendo bien a que te refieres con crear enlaces simbolicos. Uso centos :(
Esta es mi listado de directorios en /etc.

Pero no se en cual rc*.d tendria que hacer el cambio. Son directorios con mas archivos dentro:

spoiler
LOc0

Mira a ver con ntsysv -> http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-services-ntsysv.html

Con chmod +x script debería hacerse ejecutable. Lo que ya no sé seguro es si todos los scripts tienen que tener un "esqueleto" común o no.

Salu2 ;)

1 respuesta
EnZo

#13 No aparece en el listado. Hay que darlo de alta en algun sitio, pero no se en donde.
Mañana seguríe investigando que ya estoy cansado de googlear y probar...

Gracias a todos :)

LOc0

Creo que para añadir es:

#chkconfig -add tu_script

Suponiendo que tienes tu script ejecutable en /etc/init.d/tu_script

http://linux.about.com/library/cmd/blcmdl8_chkconfig.htm

Salu2 ;)

1 respuesta
EnZo

#15 Sí así es. Hay que darlo de alta con chkconfig. Lo triste es que antes ya habia pasado por esa pagina y habia probado el comando. Pero siempre me tiraba un error. Y es porque hay que añadir dos lineas cruciales para poder añadirlo. Voy a explicarlo mejor por si alguien mas le hace falta algun dia, ahora que lo he dejao perfect.

CREAR AUTOARRANQUE DE SCRIPT EN CENTOS

1º Copia tu shell script que ejecuta tu server php|java|phyton en /etc/init.d/tuscript
2º Edita tu script (# vi tuscript) y añadele dos lineas arriba, pero debajo de #!/bin/bash:

#!/bin/bash
#chkconfig: - 85 16
#description: Conkis server autorun

chkconfig: especifica los niveles de prioridad en la ejecucion.

3º Hay que añadirlo al listado de servicios

chkconfig --add /etc/init.d/tuscript

4º Por ultimo, hay que activarlo

chkconfig tuscript on

A mí me fallaba en el paso tres al no tener las lineas de dos.

Y ya como curiosidad que tambien he averiguado como se hace:

CONVERTIR UN SCRIPT EN COMANDO DE CONSOLA

1º Copia el script a /usr/bin/tuscript
2º Dale permisos de ejecucion:

chmod +x /usr/bin/tuscript

Ahora podras ejecutar tuscript como un comando en cualquier ruta.
Esto tiene un inconveniente. Y es que para hacer el autoarranque y el comando, tenemos que tener dos scripts. Uno en /usr/bin/tuscript y el otro /etc/init.d/tuscript
La solucion es borrar el de /etc/init.d y crear un enlace simbolico (Acceso directo para los winderos como yo xD)

ln /usr/bin/tuscript /etc/int.d/tuscript

A la inversa no funciona, si dejas el script en /etc/init.d/ y haces el enlace a /usr/bin/, no podras usarlo como comando. Con lo cual el enlace debe estar obligatoriamente en /etc/init.d/

Y aqui el script que he hecho sacando un poco de cada sitio:

#!/bin/bash
#chkconfig: - 85 16
#description: Conkis server autorun

SERVER_PATH="/ruta/del/archivo/php/que/es/tu/servidor.php"
OUTPUT_PATH="/ruta/del/log/archivo.log"

start() {
        pid=`php $SERVER_PATH >> $OUTPUT_PATH & echo $!`
        echo "Starting serverconkis: #$pid"
}

stop() {
        get_proc=`ps -e -o pid,command | grep $SERVER_PATH`
        echo $get_proc > get_it
        pid=`gawk -F" " '{ print $1 }' get_it`
        ptype=`gawk -F" " '{ print $2 }' get_it`
        if [ $ptype = "php" ]
        then
                echo "Stoping serverconkis: #$pid"
                kill -9 $pid
        else
                echo "The server is not running"
        fi
}


### main logic ###
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload|condrestart)
        stop
        start
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|reload}"
        start
        exit 1
esac
exit 0

Gracias de nuevo a todos :)

Usuarios habituales

  • EnZo
  • LOc0
  • PandragoQ
  • neil90
  • elkaoD
  • Poisonous