更新

更新

當我在 Windows 10 上進行任何程式設計時,我通常使用 linux 子系統,因此我的所有路徑都相對於~.我有一個 python 腳本,它在後台永遠運行,直到我終止該進程。如果沒有開啟終端,我該如何在 Windows 10 bash 上執行此操作?

我嘗試過的事情:

  • bash -c "python3 script.py來自《奔跑吧》。
  • 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(作業系統內部版本 16299.64)。

答案2

更新

微軟已經解決了這個問題。即使在bash.exe(或其他 WSL 啟動程序進程)關閉後,現在也允許後台/守護程序進程繼續運行。需要最新版本的 Win10(2018 年春季公開發布,版本 17046 或更高版本)。

以下內容為後人保留。


可悲/荒謬的是,沒有辦法做到這一點。 Microsoft 以他們無限的智慧決定 WSL(Linux 的 Windows 子系統)僅在您開啟進程時執行bash.exe。關閉最後一個(或甚至可能關閉最後一個窗戶;我不確定它是否能夠容忍無頭運行)並且 WSL 會關閉,從而終止其所有進程。

這樣做的理由是“節省資源”,這在幾個不同的層面上都是荒謬的,但最值得注意的是,該死,我的計算機有這些資源,而且它們可以使用!如果我想要一個進程運行,它就應該運行;如果我不想讓它運行,我可以殺死它。對於明確作為開發人員工具的東西,有時感覺 WSL 只能用作玩具,並且不能相信其用戶知道他們在做什麼。

無論如何,如果你想解決這個問題,請投票考慮啟用 cron 作業、守護程式和背景任務使用者之聲頁面。目前,它是得票數第二多的請求,並且處於「積壓狀態」。

答案3

是的,目前「不可能」。

但可以透過一些技巧讓它「看起來」像一個後台進程。我自己非常想要這個功能,所以幾個小時後我想出了一個糟糕但有效的解決方案。

重點是建立一個不可見的 shell,您可以使用 VBScript 啟動 WSL Bash。然後您可以讓該腳本在啟動時運行。由於某些奇怪的原因,正確的任務調度不起作用。

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。若要將其變更為 (eg) :1,請執行DISPLAY=:1下列操作等。

注意:start僅當來自批次腳本時才需要。如果是從終端來的,則不需要這個

注意:sleep需要針對每個應用程式進行不同的設定。您甚至可能需要省略它。

相關內容