
當我在 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 的任務管理器,它將顯示一個Sleep
或Python2
命令運行 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
需要針對每個應用程式進行不同的設定。您甚至可能需要省略它。