Tengo un script PHP que necesita invocar un script de shell pero no me importa en absoluto la salida. El script de shell realiza varias llamadas SOAP y tarda en completarse, por lo que no quiero ralentizar la solicitud de PHP mientras espera una respuesta. De hecho, la solicitud de PHP debería poder salir sin terminar el proceso de shell.
He mirado en las diversas exec()
, shell_exec()
, pcntl_fork()
, etc. funciones, pero ninguna de ellas parece ofrecer exactamente lo que quiero. (O, si lo hacen, no me queda claro cómo). ¿Alguna sugerencia?
php
asynchronous
shell
AdamTheHutt
fuente
fuente
nice
yionice
evitar que el script de shell abrume su sistema (p/usr/bin/ionice -c3 /usr/bin/nice -n19
. Ej. )Respuestas:
Si "no le importa la salida", ¿no se podría llamar al ejecutivo del script con
&
el proceso de fondo?EDITAR : incorporando lo que @ AdamTheHut comentó en esta publicación, puede agregar esto a una llamada a
exec
:Eso redirigirá
stdio
(primero>
) ystderr
(2>
) a/dev/null
y se ejecutará en segundo plano.Hay otras formas de hacer lo mismo, pero esta es la más simple de leer.
Una alternativa a la doble redirección anterior:
fuente
&> /dev/null &
, xdebug no generará registros si usa esto. Consulte stackoverflow.com/questions/4883171/…/dev/null
es la mejor práctica, ya que escribir en FD cerrados causa errores, mientras que los intentos de leer o escribir/dev/null
simplemente no hacen nada en silencio.Solía al por esto, ya que está empezando un proceso independiente.
fuente
www-data
) no tiene los permisos para usarat
y no puede configurarlo, puede intentar usar<?php exec('sudo sh -c "echo \"command\" | at now" ');
Ifcommand
contiene comillas, vea escapeshellarg para evitar dolores de cabezaecho "sudo command" | at now
y comentarwww-data
en/etc/at.deny
Para todos los usuarios de Windows: encontré una buena manera de ejecutar un script PHP asincrónico (en realidad funciona con casi todo).
Se basa en los comandos popen () y pclose (). Y funciona bien tanto en Windows como en Unix.
Código original de: http://php.net/manual/en/function.exec.php#86329
fuente
myscript.js
sino que escribirásnode myscript.js
. Es decir: nodo es el ejecutable, myscript.js es, bueno, el script para ejecutar. Hay una gran diferencia entre ejecutable y script.php artisan
solo ponga un comentario aquí, así que no es necesario rastrear por qué no funciona con comandosEn linux puedes hacer lo siguiente:
Esto ejecutará el comando en el símbolo del sistema y luego solo devolverá el PID, que puede verificar> 0 para asegurarse de que funcionó.
Esta pregunta es similar: ¿PHP tiene subprocesos?
fuente
action=generate var1_id=23 var2_id=35 gen_id=535
segmento). Además, dado que OP le preguntó sobre cómo ejecutar un script de shell, no necesita las porciones específicas de PHP. El código final sería:$cmd = 'nohup nice -n 10 /path/to/script.sh > /path/to/log/file.log & printf "%u" $!';
nice
sino tambiénionice
.&
ejecuta el código anterior en segundo plano, luegoprintf
se usa para la salida formateada de la$!
variable que contiene el PIDphp-execute-a-background-process tiene algunas buenas sugerencias. Creo que el mío es bastante bueno, pero soy parcial :)
fuente
En Linux, puede iniciar un proceso en un nuevo hilo independiente agregando un ampersand al final del comando
En Windows, puede usar el comando "iniciar" DOS
fuente
start
Comando probado en Windows, no se ejecuta de forma asíncrona ... ¿Podría incluir la fuente de donde obtuvo esa información?/B
parámetro. Lo he explicado aquí: stackoverflow.com/a/34612967/1709903la forma correcta (!) de hacerlo es
fork forks, setsid le dice al proceso actual que se convierta en uno maestro (no padre), execve le dice al proceso de llamada que sea reemplazado por el llamado. para que el padre pueda renunciar sin afectar al niño.
fuente
Usé esto ...
(donde
PHP_PATH
se define una constante comodefine('PHP_PATH', '/opt/bin/php5')
o similar)Pasa argumentos a través de la línea de comando. Para leerlos en PHP, vea argv .
fuente
La única forma en que encontré que realmente funcionó para mí fue:
fuente
shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown")
y todo lo que obtengo es:sh: 1: disown: not found
También encontré que Symfony Process Component es útil para esto.
Vea cómo funciona en su repositorio de GitHub .
fuente
proc_*
funciones internas.También puede ejecutar el script PHP como daemon o cronjob :
#!/usr/bin/php -q
fuente
Use un fifo con nombre.
Luego, cuando desee comenzar la tarea de larga duración, simplemente escriba una nueva línea (sin bloqueo en el archivo desencadenante).
Siempre que su entrada sea menor
PIPE_BUF
y sea unawrite()
operación única , puede escribir argumentos en el fifo y hacer que aparezcan como$REPLY
en el script.fuente
sin cola de uso, puede usar el
proc_open()
siguiente:fuente