Estou tentando portar um script de shell para a versão python muito mais legível. O script shell original inicia vários processos (utilitários, monitores, etc.) em segundo plano com "&". Como posso obter o mesmo efeito em python? Eu gostaria que esses processos não morressem quando os scripts python forem concluídos. Tenho certeza de que está relacionado ao conceito de um daemon de alguma forma, mas não consegui descobrir como fazer isso facilmente.
295
subprocess.Popen()
é a nova maneira recomendada desde 2010 (estamos em 2015 agora) e (3) a pergunta duplicada redirecionada aqui também tem uma resposta aceitasubprocess.Popen()
. Cheers :-)subprocess.Popen("<command>")
com o arquivo < comand > liderado por um shebang adequado. Funciona perfeito para mim (Debian) com scripts bash e python, implicitamente seshell
sobrevive ao processo pai.stdout
vai para o mesmo terminal que o dos pais. Portanto, isso funciona como&
em um shell que foi solicitado pelo OP. Mas inferno, todas as perguntas funcionar muito complexo, enquanto um pouco de testes mostraram que em nenhum momento;)Respostas:
Nota : esta resposta é menos atual do que era quando postada em 2009. O uso do
subprocess
módulo mostrado em outras respostas agora é recomendado nos documentosSe você deseja que seu processo inicie em segundo plano, você pode usá
system()
-lo e chamá-lo da mesma maneira que seu script shell, ou você podespawn
:(ou, alternativamente, você pode tentar o
os.P_NOWAIT
sinalizador menos portátil ).Veja a documentação aqui .
fonte
subprocess
nos dar uma dica de como desanexar um processosubprocess
?Enquanto a solução da jkp funciona, a maneira mais nova de fazer as coisas (e a maneira como a documentação recomenda) é usar o
subprocess
módulo. Para comandos simples é equivalente, mas oferece mais opções se você quiser fazer algo complicado.Exemplo para o seu caso:
Isso será executado
rm -r some.file
em segundo plano. Observe que a chamada.communicate()
do objeto retornadoPopen
será bloqueada até que seja concluída, portanto, não faça isso se quiser que ele seja executado em segundo plano:Consulte a documentação aqui .
Além disso, um ponto de esclarecimento: "Antecedentes", como você os utiliza aqui, é puramente um conceito de shell; tecnicamente, o que você quer dizer é que deseja gerar um processo sem bloquear enquanto espera que ele seja concluído. No entanto, usei "background" aqui para se referir ao comportamento semelhante ao do shell.
fonte
Popen()
para evitar o bloqueio do thread principal e, se você precisar de um daemon, consulte opython-daemon
pacote para entender como um daemon bem definido deve se comportar. Sua resposta está correta se você remover tudo que começar com "Mas tenha cuidado", exceto pelo link para os documentos do subprocesso.Você provavelmente deseja a resposta para "Como chamar um comando externo em Python" .
A abordagem mais simples é usar a
os.system
função, por exemplo:Basicamente, tudo o que você passar para a
system
função será executado da mesma forma como se você a tivesse passado para o shell em um script.fonte
Encontrei isso aqui :
No windows (win xp), o processo pai não será concluído até que o trabalho
longtask.py
seja concluído. Não é o que você deseja no script CGI. O problema não é específico do Python, na comunidade PHP os problemas são os mesmos.A solução é passar o
DETACHED_PROCESS
Sinalizador de criação de processo para aCreateProcess
função subjacente na API do win. Se você instalou o pywin32, pode importar o sinalizador do módulo win32process, caso contrário, você deve defini-lo:fonte
Use
subprocess.Popen()
com oclose_fds=True
parâmetro, que permitirá que o subprocesso gerado seja desconectado do próprio processo Python e continue em execução mesmo após a saída do Python.https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
fonte
Você provavelmente deseja começar a investigar o módulo os para criar bifurcações diferentes (abrindo uma sessão interativa e emitindo ajuda (os)). As funções relevantes são fork e qualquer uma das exec. Para lhe dar uma idéia de como iniciar, coloque algo como isto em uma função que executa o fork (a função precisa usar uma lista ou tupla 'args' como um argumento que contenha o nome do programa e seus parâmetros; você também pode querer para definir stdin, out e err para o novo thread):
fonte
os.fork()
é realmente útil, mas tem uma desvantagem notável de estar disponível apenas no * nix.threading
: stackoverflow.com/a/53751896/895245 Acho que isso pode funcionar no Windows.Capture a saída e execute em segundo plano com
threading
Conforme mencionado nesta resposta , se você capturar a saída com
stdout=
e depois tentarread()
, o processo será bloqueado.No entanto, há casos em que você precisa disso. Por exemplo, eu queria iniciar dois processos que conversam sobre uma porta entre eles e salvar o stdout em um arquivo de log e stdout.
O
threading
módulo nos permite fazer isso.Primeiro, veja como fazer a parte do redirecionamento de saída sozinha nesta pergunta: Python Popen: Escreva no stdout AND no arquivo de log simultaneamente
Então:
main.py
sleep.py
Depois de correr:
O stdout é atualizado a cada 0,5 segundos para que cada duas linhas contenha:
e cada arquivo de log contém o respectivo log para um determinado processo.
Inspirado em: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Testado no Ubuntu 18.04, Python 3.6.7.
fonte