Làm thế nào để giữ một kịch bản python chạy khi tôi đóng putty


19

Tôi sắp chạy một kịch bản python trên Ubuntu trên VPS. Đó là quá trình đào tạo máy học, vì vậy hãy dành thời gian lớn để đào tạo. Làm thế nào tôi có thể đóng putty mà không dừng quá trình đó.


1
Kiểm tra nohup.
phk

Câu trả lời:


36

Bạn có hai lựa chọn chính:

  1. Chạy lệnh với nohup. Điều này sẽ tách nó khỏi phiên của bạn và để nó tiếp tục chạy sau khi bạn ngắt kết nối:

    nohup pythonScript.py

    Lưu ý rằng thiết bị xuất chuẩn của lệnh sẽ được thêm vào một tệp được gọi nohup.outtrừ khi bạn chuyển hướng nó ( nohup pythonScript.py > outfile).

  2. Sử dụng một bộ ghép kênh màn hình như thế nào tmux. Điều này sẽ cho phép bạn ngắt kết nối với máy từ xa nhưng sau đó, khi bạn kết nối lần sau, nếu bạn chạy tmux attachlại, bạn sẽ thấy chính mình trong cùng một phiên. Lệnh vẫn sẽ chạy (nó sẽ tiếp tục chạy khi bạn đăng xuất) và bạn sẽ có thể thấy thiết bị xuất chuẩn và thiết bị xuất chuẩn của nó giống như bạn chưa bao giờ đăng xuất:

    tmux 
    pythonScript.py

    Khi bạn đã khởi chạy nó, chỉ cần đóng cửa sổ PuTTY. Sau đó, kết nối lại vào ngày hôm sau, chạy tmux attachlại và bạn quay lại nơi bạn đã bắt đầu.


4
Các lựa chọn thay thế cho 1 & 2: 1. disown2.screen
heemayl

Nó cũng có thể được đề cập byobu, một trình bao bọc xung quanh tmux hoặc màn hình.
bli

2

Công screencụ, có sẵn cho tất cả các bản phân phối Linux, hỗ trợ điều này.

Để cài đặt nó, hãy chạy apt-get install screencác bản phân phối Linux dựa trên gỡ lỗi hoặc dnf install -y screenhoặc yum install -y screencho các bản phát hành dựa trên RPM.

Để sử dụng:

$ screen

Một vỏ mới được bắt đầu. Trong shell này, bạn có thể bắt đầu tập lệnh Python của mình. Sau đó, bạn có thể nhấn Ctrl+ Shift+ Asau đó D. Nó sẽ tách thiết bị đầu cuối của bạn khỏi shell đang chạy tập lệnh của bạn. Hơn nữa, kịch bản vẫn đang chạy trong đó.

Để xem kịch bản của bạn đang chạy như thế nào, bạn có thể gọi screen -r. Điều này sẽ gắn lại thiết bị đầu cuối của bạn vào trình bao với tập lệnh Python mà bạn còn chạy trong nền.

CẬP NHẬT: như Fox đã đề cập, màn hình hoạt động kém với systemd, nhưng chúng ta có thể sử dụng systemd để bắt đầu tập lệnh, như họ nói trong ví dụ chính thức .

Ví dụ: nếu tập lệnh của bạn được bắt đầu bởi /usr/bin/myPythonScript, bạn có thể tạo tệp đơn vị Systemd, như thế này.

$ cat /etc/systemd/system/myPythonScript.service

[Unit]
Description=MyPythonScript

[Service]
ExecStart=/usr/bin/myPythonScript

[Install]
WantedBy=multi-user.target

Hơn, bạn có thể bắt đầu kịch bản này # systemctl daemon-reload # systemctl start myPythonScript

Nếu bạn muốn làm cho tập lệnh này tự động bắt đầu khi khởi động hệ thống -

# systemctl enable myPythonScript

Bất cứ lúc nào bạn có thể xem kịch bản của bạn đang chạy như thế nào

# systemctl status myPythonScript

Quảng cáo bạn có thể xem lại nhật ký của tập lệnh của mình

# journalctl -u myPythonScript -e


Lưu ý rằng screenkhông chính xác chơi độc đáo với systemdcấu hình mặc định của nó. Tôi không biết nếu Ubuntu sử dụng systemd, nhưng hành vi và cách giải quyết có thể đáng được đề cập trong câu trả lời của bạn
Fox

1

Hầu hết các quy trình có thể bị đánh lừa bằng cách chuyển hướng stdout, stderr, stdin của nó (không phải tất cả các mô tả luôn luôn cần thiết để chuyển hướng) và sử dụng &toán tử điều khiển.

Xem đó ping example.com 1>/dev/null &là công việc.

Tất nhiên, một số chương trình phức tạp hơn và yêu cầu các giải pháp như @terdon đã đề cập, nhưng thật tốt khi biết và sử dụng những gì phù hợp nhất.

EDIT: như được viết trong câu trả lời này sẽ giết chết systemdcác quá trình khi đăng xuất. Một số phiên bản của systemdquy trình tiêu diệt khi đăng xuất theo mặc định, một số phiên bản khác thì không. Hành vi này có thể được thay đổi bằng cách sửa đổi /etc/systemd/logind.conf bằng cách đặt tùy chọn sau. Như đã viết, nó cũng có thể giải quyết một số vấn đề bạn có thể gặp phải với các giải pháp của @ terdon.

từ man logind.conf:

KillUserProcesses=

Đưa ra một lập luận boolean. Định cấu hình xem các quy trình của người dùng có nên bị giết khi người dùng đăng xuất không. Nếu đúng, đơn vị phạm vi tương ứng với phiên và tất cả các quy trình bên trong phạm vi đó sẽ bị chấm dứt. Nếu sai, phạm vi bị "bỏ rơi", xem systemd.scope (5) và các quy trình không bị hủy. Mặc định là "có", nhưng xem các tùy chọn KillOnlyUsers=KillExcludeUsers=bên dưới.

Ngoài các quy trình phiên, quy trình người dùng có thể chạy dưới đơn vị người dùng đơn vị quản lý người dùng @ .service. Tùy thuộc vào cài đặt kéo dài, điều này có thể cho phép người dùng chạy các quy trình độc lập với các phiên đăng nhập của họ. Xem mô tả enable-lingertrong loginctl(1).

Lưu ý rằng cài đặt KillUserProcesses=yessẽ phá vỡ các công cụ như screen(1) và tmux(1), trừ khi chúng được chuyển ra khỏi phạm vi phiên. Xem ví dụ trong systemd-run(1).

Đọc câu trả lời liên kết để tìm hiểu thêm.


1
Điều này chỉ đơn giản là gửi quá trình đến nền. OP muốn có thể ngắt kết nối khỏi phiên ssh từ xa và tiếp tục quá trình. Điều này sẽ không giúp ích trong tình huống đó, thoát khỏi phiên từ xa sẽ dừng lệnh ngay cả khi nó ở chế độ nền.
terdon

@terdon bạn đã kiểm tra nếu ví dụ của tôi hoạt động? Tôi đã kiểm tra và nó hoạt động cho một số lệnh, như tôi đã viết trong câu trả lời của mình.
xốp bay

Vâng, tôi đã kiểm tra và vâng, tôi đã thấy rằng đôi khi lệnh tiếp tục. Tuy nhiên, tôi thường thấy rằng lệnh dừng nên trừ khi bạn có thể giải thích chính xác những lệnh nào tiếp tục hoặc cung cấp cách nhận biết trước liệu nó có tiếp tục hay không, điều này không hữu ích. Trong thực tế, ví dụ cụ thể mà bạn đã đưa ra trong bài kiểm tra tôi vừa chạy kết nối từ Arch của tôi với hệ thống Ubuntu từ xa.
terdon

@terdon buồn cười, tôi đã kiểm tra cái này trên ArchLinux cục bộ kết nối với PLD từ xa. Quy tắc duy nhất hoạt động mọi lúc là "chương trình có sử dụng isatty()và thoát nếu không?"
xốp bay

Điều đó có thể xứng đáng với câu hỏi của riêng mình. Tôi biết tôi đã từng luôn cần nohup, và rồi đến một lúc nào đó có gì đó thay đổi và đôi khi tôi đã không làm thế. Mặc dù vậy, tôi không thể thấy sự tương đồng có thể như thế nào, nếu bạn thoát khỏi vỏ cha mẹ, điều đó cũng sẽ giết chết đứa trẻ. Nhưng có, đôi khi không. Tôi đoán nó phải được cấu hình bằng cách nào đó.
terdon
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.