Chạy quy trình nền bash trên Windows 10 mà không cần thiết bị đầu cuối mở


13

Tôi thường sử dụng hệ thống con linux khi tôi lập trình bất cứ thứ gì trên Windows 10 vì vậy tất cả các đường dẫn của tôi đều liên quan đến ~. Tôi có một kịch bản python chạy mãi trong nền cho đến khi tôi giết tiến trình. Làm thế nào để tôi làm điều đó trên Windows 10 bash mà không có thiết bị đầu cuối mở?

Những điều tôi đã thử:

  • bash -c "python3 script.py từ Chạy.
  • nohup python3 -u script.py sau đó đóng thiết bị đầu cuối.
  • setsid python3 script.py sau đó đóng thiết bị đầu cuối.

Không ai trong số này làm việc. Có cách nào để làm việc này không? Ngoài ra, có cách nào để thay đổi đường dẫn để chúng hoạt động nếu tôi chạy tập lệnh từ W10 VÀ bash mà không phải chuyển đổi chúng mỗi lần không?

Câu trả lời:


7

Một bổ sung gần đây cho WSL cho phép bắt đầu các lệnh wsl trực tiếp từ menu 'run' hoặc Start. Bạn có thể nối thêm dấu và vào lệnh (hành vi shell bình thường), kết quả là một bashthiết bị đầu cuối tạm thời sẽ biến mất ngay lập tức nhưng lệnh vẫn tiếp tục.

Ví dụ, trong Bắt đầu »Chạy :

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

Nếu bạn vào Trình quản lý tác vụ của Windows, nó sẽ hiển thị một lệnh Sleephoặc Python2chạy trong 20 giây, sau đó tự xóa.

Một điều tôi đã tìm thấy là các biến môi trường không có sẵn. Chẳng hạn, DISPLAYnếu được đặt trong phương thức bình thường của windows, sẽ không được truyền cho WSL. Đối với điều này, cần phải có một cách để vượt qua các biến này. Ngay cả khi lệnh không hỗ trợ cài đặt biến cần thiết thông qua đối số dòng lệnh, bạn vẫn có thể tự thực hiện bằng cách sử dụng bash:

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

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

Lưu ý: Tôi hiện đang chạy win10_64, Phiên bản 1709 (OS Build 16299.64).


13

Cập nhật

Microsoft đã giải quyết điều này. Các quy trình nền / daemon hiện được phép tiếp tục chạy ngay cả sau khi bash.exe(hoặc quá trình khởi chạy WSL khác) bị đóng. Bản dựng gần đây của Win10 (mùa xuân 2018 cho các bản phát hành công khai, bản dựng 17046 trở lên) là bắt buộc.

Dưới đây được bảo tồn cho hậu thế.


Đáng buồn / vô lý, không có cách nào để làm điều này. Microsoft, theo trí tuệ vô hạn của họ, đã quyết định rằng WSL (Hệ thống con Windows cho Linux) sẽ chỉ chạy trong khi bạn có một bash.exequy trình mở. Đóng cửa sổ cuối cùng (hoặc thậm chí có thể đóng cửa sổ cuối cùng ; tôi không chắc liệu nó có chịu được việc chạy không đầu không) và WSL tắt, giết chết tất cả các quy trình của nó.

Lý do cho điều này là "để bảo tồn tài nguyên", điều này là vô lý ở nhiều cấp độ khác nhau nhưng đáng chú ý nhất là vì, chết tiệt, máy tính của tôi có những tài nguyên đó và chúng được sử dụng! Nếu tôi muốn một tiến trình để chạy, nó sẽ chạy; nếu tôi không muốn nó chạy, tôi có thể giết nó. Đối với một cái gì đó được dự định rõ ràng là một công cụ dành cho nhà phát triển, đôi khi có cảm giác như WSL chỉ có thể sử dụng như một thứ đồ chơi và người dùng không thể tin tưởng để biết họ đang làm gì.

Dù sao đi nữa, nếu bạn muốn sửa lỗi này, hãy bỏ phiếu cho Xem xét kích hoạt các công việc định kỳ, trình nền và các tác vụ nền trên trang UserVoice . Đây hiện là yêu cầu được bình chọn nhiều thứ hai và là "tồn đọng".


"Đáng chú ý nhất là bởi vì, chết tiệt, máy tính của tôi có những tài nguyên đó và chúng ở đó để sử dụng" rất tốt! nó thực sự làm vùi dập tâm trí ...
cuộc không kích

Tôi đã xây dựng 17134 và không thể có một công việc nền mà không có cửa sổ bash.
John Pick

@JohnPick Họ sẽ không khởi động tự động sau khi khởi động lại, nhưng họ nên tiếp tục chạy khi cửa sổ đóng (tất nhiên là miễn là họ không gắn với nó).
CBHacking

@CBHacking Để cụ thể hơn, nếu tôi khởi động máy chủ Node.js ở chế độ nền, thì đó là cả công việc ( jobs) và quy trình ( ps aux). Tôi có thể sử dụng fgđể đưa nó lên nền trước. Nhưng, sau khi tôi đóng cửa sổ bash cuối cùng và mở một cửa sổ bash mới, công việc không còn nữa, quá trình vẫn đang chạy và tôi không thể chuyển quá trình sang tiền cảnh. Xin lỗi nếu thuật ngữ của tôi bị tắt.
John Pick

@JohnPick Ah, đó là một vấn đề hoàn toàn khác - câu hỏi này là về các quy trình, không phải về quản lý công việc shell - và nên được hỏi ở nơi khác, nhưng câu trả lời đủ đơn giản tôi sẽ đưa ra ở đây: khởi chạy quy trình theo tmuxhoặc screenđể hỗ trợ gắn lại vào một thiết bị đầu cuối khác. Các máy Linux (và các máy * nix) khác chạy tự nhiên có cùng giới hạn.
CBHacking

2

Vâng, đó là "không thể" vào lúc này.

Nhưng có thể để nó "xuất hiện" giống như một quá trình nền với một số mánh khóe. Tôi muốn chức năng này khá tệ cho bản thân mình nên sau một vài giờ tôi đã nghĩ ra một giải pháp hiệu quả nhưng tồi tệ.

Điểm chính là tạo một lớp vỏ vô hình mà bạn khởi chạy WSL Bash với VBScript. Sau đó, bạn có thể chạy tập lệnh đó khi khởi động. Lập kế hoạch nhiệm vụ phù hợp đã không làm việc vì một số lý do lạ.

Phía Linux để kích hoạt trình tiện ích, bạn có thể có hệ thống khởi động thô sơ của riêng bạn lạm dụng .bashrc chẳng hạn.

Quá trình này được trình bày chi tiết ở đây trong tài liệu này, tôi đã viết https://emil.fi/bashwin . Tôi đã không thực hiện giám sát nhiệm vụ nhưng nó sẽ khá dễ dàng để mở rộng.


2

Bạn đã thử giải pháp này ?

Nó sử dụng một trình trợ giúp WSH để khởi chạy bất kỳ ứng dụng nào bị ẩn.

Sau đó, bạn có thể chỉ cần tạo một tác vụ mới trong Tak Lập lịch để khởi chạy lệnh khi bạn đăng nhập. Cái gì đó nhưwscript <path to runHidden.vbs> bash.exe -c "python script.py"


2

Nó đã đưa tôi mãi mãi nhưng tôi đã tìm thấy một cách làm việc phức tạp một cách ngu ngốc (từ một tệp bó):

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

Đây là một sự cố về những gì nó làm và tại sao:

  • `start`: để làm cho cửa sổ tệp bó biến mất
  • `bash -c`: cho phép bạn chạy lệnh bash
  • `HIỂN THỊ =: 0`: đặt máy chủ X của bạn
  • `[lệnh]`: lệnh / lệnh của bạn (`[lệnh && [lệnh]`)
  • `&`: để làm cho lệnh tiếp theo chạy sau khi nó bắt đầu và không phải khi nó hoàn thành
  • `ngủ 0,5`: để đảm bảo quá trình đã bắt đầu
  • '&& `: để làm cho lệnh chạy tiếp theo sau khi nó được thực hiện và không phải khi nó bắt đầu
  • `kill -n 9 $$`: để giết shell bash để nó chỉ là ứng dụng đồ họa

Lưu ý: DISPLAY=:0đặt nó vào máy chủ x tại :0. Để thay đổi nó thành (ví dụ) :1, hãy làm, DISPLAY=:1v.v.

Lưu ý: startchỉ được yêu cầu nếu nó từ một tập lệnh bó. Nếu nó từ thiết bị đầu cuối, bạn không cần điều này

Lưu ý: sleepcần phải được đặt khác nhau cho mỗi ứng dụng. Bạn thậm chí có thể cần phải bỏ qua nó.


0

Tôi không biết Trình quản lý dịch vụ Windows (SrvMan) từ http://tools.sysprogs.org/srvman/ sẽ hoạt động tốt như thế nào đối với bạn, nhưng nó đã làm việc cho tôi cho các chương trình khác. Trên thực tế, tôi đã thử chạy "bash.exe" như một dịch vụ để xem nó có hoạt động không và tôi đoán tôi phải sửa lại một chút nữa để LAMP thực sự hoạt động ở chế độ nền.


1
Làm thế nào để giải quyết câu hỏi về cách chạy tập lệnh Python trong nền?
Scott
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.