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

niceyioniceevitar 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/nully 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/nulles la mejor práctica, ya que escribir en FD cerrados causa errores, mientras que los intentos de leer o escribir/dev/nullsimplemente 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 usaraty no puede configurarlo, puede intentar usar<?php exec('sudo sh -c "echo \"command\" | at now" ');Ifcommandcontiene comillas, vea escapeshellarg para evitar dolores de cabezaecho "sudo command" | at nowy comentarwww-dataen/etc/at.denyPara 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.jssino 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 artisansolo 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=535segmento). 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" $!';nicesino tambiénionice.&ejecuta el código anterior en segundo plano, luegoprintfse 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
startComando probado en Windows, no se ejecuta de forma asíncrona ... ¿Podría incluir la fuente de donde obtuvo esa información?/Bpará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_PATHse 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 foundTambié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 -qfuente
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_BUFy sea unawrite()operación única , puede escribir argumentos en el fifo y hacer que aparezcan como$REPLYen el script.fuente
sin cola de uso, puede usar el
proc_open()siguiente:fuente