更新

更新

在 Windows 10 上编程时,我通常使用 linux 子系统,因此我的所有路径都与 相关~。我有一个 python 脚本,它会在后台永远运行,直到我终止该进程。在没有打开终端的情况下,我该如何在 Windows 10 bash 上执行此操作?

我尝试过的事情:

  • bash -c "python3 script.py来自 Run。
  • nohup python3 -u script.py然后关闭终端。
  • setsid python3 script.py然后关闭终端。

这些都不起作用。有办法吗?或者,如果我从 W10 和 bash 运行脚本,而不必每次都切换它们,那么有没有办法改变路径,使它们正常工作?

答案1

WSL 最近新增了一项功能,允许直接从“运行”或“开始”菜单启动 wsl 命令。您可以在命令后附加一个 & 符号(正常的 shell 行为),这样会产生一个瞬时bash终端,它会立即消失,但命令会继续执行。

例如,在开始运行

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

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

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

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

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

注意:我目前正在运行 win10_64,版本 1709(OS Build 16299.64)。

答案2

更新

微软已经解决了这个问题。现在允许后台/守护进程在bash.exe(或其他 WSL 启动器进程)关闭后继续运行。需要最新版本的 Win10(2018 年春季公开发布,版本 17046 或更高版本)。

以下内容为后人保留。


可悲/荒谬的是,没有办法做到这一点。微软凭借其无限的智慧,决定 WSL(适用于 Linux 的 Windows 子系统)仅在您打开进程时运行bash.exe。关闭最后一个(或可能甚至关闭最后一个窗户;我不确定它是否能容忍无头运行)并且 WSL 关闭,终止其所有进程。

这样做的理由是“为了节省资源”,这在很多层面上都是荒谬的,但最明显的是,该死的,我的电脑有这些资源,它们就是用来使用的!如果我想运行一个进程,它就应该运行;如果我不想让它运行,我可以杀死它。对于明确用作开发人员工具的东西,有时感觉 WSL 只能用作玩物,不能相信它的用户知道他们在做什么。

无论如何,如果你想解决这个问题,请投票考虑启用 cron 作业、守护进程和后台任务UserVoice 页面。这是目前获得投票第二多的请求,并且“处于积压状态”。

答案3

是的,目前是“不可能”的。

但通过一些小技巧,可以让它“出现”为后台进程。我自己也非常想要这个功能,所以几个小时后我想出了一个虽然糟糕但可行的解决方案。

重点是创建一个不可见的 shell,使用 VBScript 将 WSL Bash 启动到该 shell。然后,您可以在启动时运行该脚本。由于某些奇怪的原因,正确的任务调度不起作用。

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

这个过程在我写的这篇文档中有详细说明https://emil.fi/bashwin。我没有实现任务监控,但它应该很容易扩展。

答案4

我花了很长时间才找到一种非常复杂的方法(从批处理文件中):

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-server :0。要将其更改为(例如):1,请执行DISPLAY=:1等。

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

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

相关内容