Eu tenho um script PHP que precisa chamar um shell script, mas não se importa com a saída. O script de shell faz várias chamadas SOAP e é lento para concluir, portanto, não quero abrandar a solicitação do PHP enquanto aguarda uma resposta. De fato, a solicitação do PHP deve poder sair sem encerrar o processo do shell.
Eu olhei para os vários exec()
, shell_exec()
, pcntl_fork()
funções, etc., mas nenhum deles parecem oferecer exatamente o que eu quero. (Ou, se o fizerem, não está claro para mim como.) Alguma sugestão?
php
asynchronous
shell
AdamTheHutt
fonte
fonte
nice
eionice
para impedir que o script shell de sobrecarregar o seu sistema (por exemplo/usr/bin/ionice -c3 /usr/bin/nice -n19
)Respostas:
Se "não se importa com a saída", o executivo do script não pode ser chamado com o
&
pano de fundo do processo?EDIT - incorporando o que o @ AdamTheHut comentou neste post, você pode adicioná-lo a uma chamada para
exec
:Isso redirecionará ambos
stdio
(primeiro>
) estderr
(2>
) para/dev/null
e será executado em segundo plano.Existem outras maneiras de fazer a mesma coisa, mas essa é a mais simples de ler.
Uma alternativa ao redirecionamento duplo acima:
fonte
&> /dev/null &
, xdebug não irá gerar logs se você usar isso. Verifique stackoverflow.com/questions/4883171/…/dev/null
é a melhor prática, pois gravar em FDs fechados causa erros, enquanto as tentativas de ler ou gravar/dev/null
simplesmente não fazem nada silenciosamente.Eu usei a para isso, como ele está realmente começando um processo independente.
fonte
www-data
) não tem as permissões para usoat
e você não pode configurá-lo para, você pode tentar usar<?php exec('sudo sh -c "echo \"command\" | at now" ');
Secommand
contém aspas, consulte escapeshellarg para poupar dores de cabeçaecho "sudo command" | at now
e comentarwww-data
em/etc/at.deny
Para todos os usuários do Windows: Encontrei uma boa maneira de executar um script PHP assíncrono (na verdade, ele funciona com quase tudo).
É baseado nos comandos popen () e pclose (). E funciona bem no Windows e no Unix.
Código original de: http://php.net/manual/en/function.exec.php#86329
fonte
myscript.js
mas escrevenode myscript.js
. Ou seja: node é o executável, myscript.js é, bem, o script a ser executado. Há uma enorme diferença entre executável e script.php artisan
basta colocar um comentário aqui para que não seja necessário rastrear por que ele não funcionará com comandosNo linux, você pode fazer o seguinte:
Isso executará o comando no prompt de comando e retornará o PID, que você pode verificar> 0 para garantir que funcionou.
Esta pergunta é semelhante: O PHP tem threading?
fonte
action=generate var1_id=23 var2_id=35 gen_id=535
segmento). Além disso, como o OP perguntou sobre a execução de um script de shell, você não precisa das partes específicas do PHP. O código final seria:$cmd = 'nohup nice -n 10 /path/to/script.sh > /path/to/log/file.log & printf "%u" $!';
nice
mas tambémionice
.&
pistas anteriores código no fundo, em seguida,printf
é usado para a saída formatado da$!
variável que contém o PIDO php-execute-a-background-process tem algumas boas sugestões. Eu acho que o meu é muito bom, mas sou tendencioso :)
fonte
No Linux, você pode iniciar um processo em um novo encadeamento independente anexando um e comercial no final do comando
No Windows, você pode usar o comando DOS "start"
fonte
start
Comando testado no Windows, ele não é executado de forma assíncrona ... Você poderia incluir a fonte de onde obteve essas informações?/B
parâmetro. Eu expliquei aqui: stackoverflow.com/a/34612967/1709903o caminho certo (!) para fazê-lo é
fork garfos, setsid informa o processo atual para se tornar um master (sem pai), execve informa o processo de chamada a ser substituído pelo chamado. para que o pai possa sair sem afetar o filho.
fonte
Eu usei isso ...
(onde
PHP_PATH
é uma constante definida comodefine('PHP_PATH', '/opt/bin/php5')
semelhante ou similar)Ele passa argumentos através da linha de comando. Para lê-los em PHP, consulte argv .
fonte
A única maneira que eu descobri que realmente funcionou para mim foi:
fonte
shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown")
e tudo o que recebo é:sh: 1: disown: not found
Eu também achei o Symfony Process Component útil para isso.
Veja como ele funciona em seu repositório GitHub .
fonte
proc_*
funções internas.Você também pode executar o script PHP como daemon ou cronjob :
#!/usr/bin/php -q
fonte
Use um fifo nomeado.
Depois, sempre que desejar iniciar a tarefa de longa execução, basta escrever uma nova linha (sem bloqueio no arquivo acionador.
Desde que sua entrada seja menor que
PIPE_BUF
e seja umawrite()
operação única , você pode escrever argumentos no fifo e fazê-los aparecer como$REPLY
no script.fonte
sem fila de uso, você pode usar o
proc_open()
seguinte:fonte