
Eu normalmente uso o subsistema Linux quando estou programando qualquer coisa no Windows 10, então todos os meus caminhos são relativos ao ~
. Eu tenho um script python que é executado indefinidamente em segundo plano até encerrar o processo. Como eu faria isso no Windows 10 sem um terminal aberto?
Coisas que tentei:
bash -c "python3 script.py
de Corre.nohup python3 -u script.py
em seguida, fechando o terminal.setsid python3 script.py
em seguida, fechando o terminal.
Nada disso funcionou. Existe uma maneira de fazer isso? Como alternativa, existe uma maneira de alterar os caminhos para que funcionem se eu executar o script do W10 E do bash sem precisar alterná-los todas as vezes?
Responder1
Uma adição recente ao WSL permite iniciar comandos wsl diretamente do menu ‘executar’ ou Iniciar. Você pode anexar um e comercial ao comando (comportamento normal do shell), o que resulta em um bash
terminal momentâneo que desaparece imediatamente, mas o comando continua.
Exemplos, dentroComece a correr:
wsl sleep 20 &
wsl python -c 'import time; time.sleep(20);' &
Se você entrar no Gerenciador de Tarefas do Windows, ele mostrará um comando Sleep
ou Python2
em execução por 20 segundos e depois será autolimpante.
Uma coisa que descobri é que as variáveis de ambiente não estão disponíveis. Por exemplo, DISPLAY
se definido no método normal do Windows, não é passado para WSL. Para isso, é necessário que haja uma forma de passar essas variáveis. Mesmo que o comando não suporte a configuração da variável necessária por meio de um argumento de linha de comando, é possível fazer isso sozinho bash
:
# direct, command-dependent
wsl emacs --display=:0 &
# indirect, more flexible
wsl bash -c "DISPLAY=:0 emacs" &
NB: Atualmente estou executando o win10_64, versão 1709 (OS Build 16299.64).
Responder2
Atualizar
A Microsoft resolveu isso. Os processos em segundo plano/daemon agora podem continuar em execução mesmo após bash.exe
(ou outro processo do iniciador WSL) ser fechado. É necessária uma versão recente do Win10 (primavera de 2018 para versões públicas, versão 17046 ou superior).
O abaixo é preservado para a posteridade.
Infelizmente/absurdamente, não há como fazer isso. A Microsoft, em sua infinita sabedoria, decidiu que o WSL (Windows Subsystem for Linux) só será executado enquanto você tiver um bash.exe
processo aberto. Feche o último (ou possivelmente feche o últimojanela; Não tenho certeza se ele tolerará ser executado sem cabeça) e o WSL será encerrado, matando todos os seus processos.
A justificativa para isso foi “para conservar recursos”, o que é um absurdo em vários níveis, mas principalmente porque, caramba, meu computador tem esses recursos e eles estão aí para serem usados! Se eu quiser que um processo seja executado, ele deverá ser executado; se eu não quiser que ele corra, posso matá-lo. Para algo explicitamente concebido como uma ferramenta de desenvolvedor, às vezes parece que o WSL só pode ser usado como um brinquedo e não se pode confiar que seus usuários saibam o que estão fazendo.
De qualquer forma, se você quiser que isso seja corrigido, vote emConsidere habilitar cron jobs, daemons e tarefas em segundo planosobrea página UserVoice. Atualmente é a segunda solicitação mais votada e está “na lista de pendências”.
Responder3
Sim, é "impossível" no momento.
Mas é possível fazer com que "apareça" como um processo em segundo plano com alguns truques. Eu mesmo queria muito essa funcionalidade, então, depois de algumas horas, encontrei uma solução ruim, mas funcional.
O ponto principal é criar um shell invisível no qual você inicia o WSL Bash com VBScript. Você pode então executar esse script na inicialização. O agendamento adequado de tarefas não funcionou por algum motivo estranho.
Lado Linux para habilitar daemons você pode ter seu próprio sistema de inicialização rudimentar que abusa de .bashrc por exemplo.
O processo está detalhado aqui neste documento que escrevihttps://emil.fi/bashwin. Não implementei o monitoramento de tarefas, mas deve ser bem fácil de estender.
Responder4
Demorei uma eternidade, mas encontrei uma maneira estupidamente complicada de fazer isso (a partir de um arquivo em lote):
start bash -c "DISPLAY=:0 [command] & (sleep 0.5 && kill -n 9 $$)"
Aqui está um resumo do que ele faz e por quê:
- `start`: para fazer com que a janela do arquivo em lote desapareça
- `bash -c`: permite executar um comando bash
- `DISPLAY=:0`: define seu servidor X
- `[command]`: seu comando/comandos (`[command && [command]`)
- `&`: para fazer o próximo comando ser executado depois delecomeçae não quando éfeito
- `sleep 0.5`: para garantir que o processo foi iniciado
- `&&`: para fazer o próximo comando ser executado apósfeitoe não quandocomeça
- `kill -n 9 $$`: para matar o shell bash, então é apenas a aplicação gráfica
Nota:
DISPLAY=:0
configura-o para o servidor x em:0
. Para alterá-lo para (eg):1
, façaDISPLAY=:1
etc.Nota:
start
só é necessário se for de um script em lote. Se for do terminal, você não precisa dissoNota:
sleep
precisa ser definido de forma diferente para cada aplicação. Você pode até precisar omiti-lo.