在没有打开终端的情况下在Windows 10上运行bash后台进程


13

在Windows 10上进行任何编程时,我通常使用linux子系统,因此所有路径都相对于~。我有一个永远在后台运行的python脚本,直到杀死该进程为止。在没有开放终端的Windows 10 bash上,我该怎么做?

我尝试过的事情:

  • bash -c "python3 script.py 从运行。
  • nohup python3 -u script.py 然后关闭终端。
  • setsid python3 script.py 然后关闭终端。

这些都不起作用。有没有办法做到这一点?另外,如果我从W10 AND bash运行脚本,而不必每次都切换它们,是否有一种方法可以更改路径,使它们起作用?

Answers:


7

WSL的最新功能允许直接从“运行”或“开始”菜单启动wsl命令。您可以在命令后面附加一个&符号(正常的shell行为),这会导致瞬时bash终止,该终止立即消失,但命令继续。

开始»运行中的示例:

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

如果进入Windows的任务管理器,它将显示SleepPython2命令运行20秒钟,然后自动清除。

我发现的一件事是环境变量不可用。例如,DISPLAY如果在Windows normal方法中设置,则不会传递给WSL。为此,需要一种传递这些变量的方法。即使该命令不支持通过命令行参数设置所需的变量,也可以使用bash其自身进行设置:

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

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

注意:我当前正在运行win10_64,版本1709(操作系统内部版本16299.64)。


13

更新资料

Microsoft已解决此问题。现在,即使bash.exe关闭了(或其他WSL启动程序)进程,后台/守护进程也可以继续运行。需要最新版本的Win10(2018年春季公开发布,版本17046或更高版本)。

以下内容保留供后代使用。


可悲/荒唐的是,没有办法做到这一点。微软以其无穷的智慧决定WSL(Linux的Windows子系统)仅在您bash.exe打开一个进程时运行。关闭最后一个窗口(或者甚至关闭最后一个窗口;我不确定它是否可以忍受无头运行),并且WSL关闭,杀死所有进程。

这样做的理由是“节省资源”,这在几个不同的层面上都是荒谬的,但是最明显的原因是,该死,我的计算机拥有这些资源并且可以使用它们!如果我想运行一个进程,它应该运行;如果我不希望它运行,我可以杀死它。对于明确打算用作开发人员工具的东西,有时会觉得WSL只能用作玩物,而不能信任其用户知道他们在做什么。

无论如何,如果要解决此问题,在UserVoice页面上投票考虑启用cron作业,守护程序和后台任务。目前,它是投票数第二高的请求,并且是“待办事项列表”。


“最重要的是,该死,我的计算机拥有这些资源,因此可以使用它们”。它真的使人感到困惑……
空袭

我有内部版本17134,没有bash窗口就无法进行后台作业。
约翰·皮克

@JohnPick它们在重新启动后不会自动启动,但是在关闭窗口时它们应该保持运行(当然,只要它们没有连接到窗口即可)。
CBHacking

@CBHacking更具体地说,如果我在后台启动Node.js服务器,则它既是作业(jobs)又是进程(ps aux)。我可以fg用来将它带到前台。但是,在我关闭最后一个bash窗口并打开一个新的bash窗口之后,该作业消失了,该进程仍在运行,并且无法将其移到前台。对不起,如果我的术语不正确。
约翰·皮克

@JohnPick Ah,这是一个完全不同的问题-这个问题是关于流程的,而不是关于Shell作业管理的-应该在其他地方提出来的,但是答案很简单,我将在这里给出:在tmuxscreen支持下启动流程重新连接到另一个终端。本地运行的Linux(和其他* nix)计算机具有相同的限制。
CBHacking

2

是的,此刻“不可能”。

但是有可能使它像一些后台程序一样“出现”在后台过程中。我本人希望此功能非常糟糕,所以几个小时后,我想出了一个糟糕但可行的解决方案。

要点是创建一个不可见的外壳,然后使用VBScript将WSL Bash启动到该外壳。然后,您可以在启动时运行该脚本。出于某些奇怪的原因,正确的任务计划无法正常工作。

在Linux端启用守护程序,您可以拥有自己的基本启动系统,例如,它滥用.bashrc。

我在https://emil.fi/bashwin撰写的本文档中对此过程进行了详细说明。我没有实现任务监视,但是应该很容易扩展。


2

您是否尝试过解决方案?

它使用WSH帮助程序来启动任何隐藏的应用程序。

然后,您只需在Tak Scheduler中创建一个新任务,以在登录时启动该命令。就像是wscript <path to runHidden.vbs> bash.exe -c "python script.py"


2

我花了很长时间,但是我发现了一个愚蠢的复杂方法(从批处理文件中):

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

以下是其功能及其原因的细分:

  • `start`:使批处理文件窗口消失
  • bash -c:让您运行bash命令
  • DISPLAY =:0:设置您的X服务器
  • `[command]`:您的命令/命令(`[command && [command]`)
  • `&`:使下一个命令在启动后而不是在完成时运行
  • `sleep 0.5`:确保进程已开始
  • `&&`:使下一个命令在完成后而不是在启动时运行
  • `kill -n 9 $$`:杀死bash shell,因此它只是图形应用程序

注意:DISPLAY=:0将其设置为x服务器:0。要将其更改为(例如):1,请执行其他操作DISPLAY=:1

注意:start仅当来自批处理脚本时才需要。如果来自终端,则不需要

注意:sleep每个应用程序需要设置不同。您甚至可能需要忽略它。


0

我不知道来自http://tools.sysprogs.org/srvman/的 Windows服务管理器(SrvMan)将为您提供多大的 帮助,但是对于其他程序,它已经为我提供了帮助。实际上,我确实尝试将“ bash.exe”作为服务运行,以查看其是否可以正常运行,而且我想我还需要进行一些修补才能使LAMP在后台实际运行。


1
这如何解决如何在后台运行Python脚本的问题?
斯科特(Scott)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.