Executando um processo de segundo plano do bash no Windows 10 sem um terminal aberto

13

Normalmente, uso o subsistema linux quando estou programando algo no Windows 10, portanto todos os meus caminhos são relativos ~. Eu tenho um script python que é executado para sempre em segundo plano até eu matar o processo. Como eu faria isso no Windows 10 bash sem um terminal aberto?

Coisas que tentei:

  • bash -c "python3 script.py de Executar.
  • nohup python3 -u script.py depois fechando o terminal.
  • setsid python3 script.py depois 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 a partir do W10 AND bash sem precisar trocá-los sempre?

Cinza
fonte

Respostas:

7

Uma adição recente ao WSL permite iniciar comandos wsl diretamente no menu 'executar' ou Iniciar. Você pode anexar um e comercial ao comando (comportamento normal do shell), o que resulta em um bashterminal momentâneo que desaparece imediatamente, mas o comando continua.

Exemplos, em Iniciar »Executar :

wsl sleep 20 &
wsl python -c 'import time; time.sleep(20);' &

Se você for ao Gerenciador de tarefas do Windows, ele mostrará um comando Sleepou Python2sendo executado por 20 segundos e, em seguida, será limpo automaticamente.

Uma coisa que descobri é que as variáveis ​​de ambiente não estão disponíveis. Por exemplo, DISPLAYse definido no método normal do Windows, não é passado para o WSL. Para isso, é preciso haver uma maneira 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 fazê-lo usando- bashse:

# direct, command-dependent
wsl emacs --display=:0 &

# indirect, more flexible
wsl bash -c "DISPLAY=:0 emacs" &

NB: No momento, estou executando o win10_64, versão 1709 (compilação do sistema operacional 16299.64).

r2evans
fonte
13

Atualizar

A Microsoft abordou isso. Os processos em segundo plano / daemon agora podem continuar em execução mesmo após o bash.exefechamento (ou outro processo do iniciador da WSL). É necessária uma compilação recente do Win10 (primavera de 2018 para lançamentos públicos, compilaçã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 para Linux) será executado apenas enquanto você tiver um bash.exeprocesso aberto. Feche a última (ou possivelmente feche a última janela ; não tenho certeza se ela tolerará ser executada sem cabeça) e o WSL será encerrado, matando todos os seus processos.

A justificativa para isso era "conservar recursos", o que é absurdo em vários níveis diferentes, mas principalmente porque, caramba, meu computador possui esses recursos e eles estão lá para serem usados! Se eu quiser que um processo seja executado, ele deve ser executado; se não quero que funcione, posso matá-lo. Para algo explicitamente planejado como uma ferramenta de desenvolvedor, às vezes parece que a WSL é apenas utilizável como um brinquedo e não se pode confiar em seus usuários para saber o que estão fazendo.

De qualquer forma, se você deseja corrigir isso, vote em Considere ativar os trabalhos cron, daemons e tarefas em segundo plano na página UserVoice . Atualmente, é o segundo pedido mais votado e está "na lista de pendências".

CBHacking
fonte
"principalmente porque, caramba, meu computador possui esses recursos e eles estão lá para serem usados" muito bem colocado! ele realmente confunde a mente ...
ataque aéreo
Eu tenho o build 17134 e não posso ter um trabalho em segundo plano sem uma janela do bash.
John Pick
@JohnPick Eles não serão iniciados automaticamente após uma reinicialização, mas devem permanecer em execução quando a janela estiver fechada (desde que não estejam conectados a ela, é claro).
precisa saber é o seguinte
@CBHacking Para ser mais específico, se eu iniciar um servidor Node.js. em segundo plano, será um trabalho ( jobs) e um processo ( ps aux). Eu posso usar fgpara trazê-lo para o primeiro plano. Mas, depois de fechar a última janela do bash e abrir uma nova janela do bash, o trabalho foi encerrado, o processo ainda está em execução e não consigo mover o processo para o primeiro plano. Desculpe se minha terminologia está desativada.
John Escolha
@JohnPick Ah, essa é uma questão completamente diferente - essa questão é sobre processos, não sobre gerenciamento de tarefas do shell - e deveria ter sido feita em outro lugar, mas a resposta é simples o suficiente que darei aqui: inicie o processo sob tmuxou screenpara apoiar reconectando a um terminal diferente. As máquinas Linux (e outras * nix) em execução nativamente têm a mesma limitação.
precisa saber é o seguinte
2

Sim, é "impossível" no momento.

Mas é possível que ele "apareça" como um processo em segundo plano com alguns truques. Eu queria muito essa funcionalidade, então, depois de algumas horas, encontrei uma solução de merda, mas funcional.

O ponto principal é criar um shell invisível para o qual você inicia o WSL Bash com o VBScript. Você pode então executar esse script na inicialização. O agendamento adequado de tarefas não funcionou por algum motivo estranho.

No lado do Linux para ativar daemons, você pode ter seu próprio sistema de inicialização rudimentar que abusa do .bashrc, por exemplo.

O processo está detalhado aqui neste documento que escrevi https://emil.fi/bashwin . Não implementei o monitoramento de tarefas, mas deve ser bem fácil de estender.

Emil
fonte
2

Você já tentou esta solução?

Ele usa um auxiliar WSH para iniciar qualquer aplicativo oculto.

Em seguida, você pode apenas criar uma nova tarefa no Tak Scheduler para iniciar o comando quando fizer login. Algo comowscript <path to runHidden.vbs> bash.exe -c "python script.py"

Magnus
fonte
2

Demorei uma eternidade, mas achei uma maneira estupidamente complicada de fazer isso (a partir de um arquivo em lotes):

start bash -c "DISPLAY=:0 [command] & (sleep 0.5 && kill -n 9 $$)"

Aqui está uma descrição do que ele faz e por quê:

  • `start`: para fazer a janela do arquivo em lotes desaparecer
  • `bash -c`: permite executar um comando bash
  • `DISPLAY =: 0`: define seu servidor X
  • `[command]`: seu comando / comandos (`[command && [command]`)
  • `&`: para executar o próximo comando após o início e não quando terminar
  • `sleep 0.5`: para garantir que o processo foi iniciado
  • `&&`: para executar o próximo comando depois que terminar e não quando iniciar
  • `kill -n 9 $$`: para matar o shell bash, por isso é apenas a aplicação gráfica

Nota: DISPLAY=:0define para o servidor x em :0. Para alterá-lo para (por exemplo) :1, faça DISPLAY=:1etc.

Nota: startsó é necessário se for de um script em lote. Se é do terminal, você não precisa disso

Nota: sleepprecisa ser definido de maneira diferente para cada aplicativo. Você pode até precisar omitir isso.

Electroboss
fonte
0

Não sei se o Windows Service Manager (SrvMan) de http://tools.sysprogs.org/srvman/ funcionaria para você, mas funcionou para mim em outros programas. Na verdade, tentei executar o "bash.exe" como um serviço para ver se funcionaria, e acho que tenho que mexer um pouco mais para que o LAMP realmente funcione em segundo plano.

Charles McDonald
fonte
1
Como isso aborda a questão de como executar um script Python em segundo plano?
Scott