Quá trình java vẫn bị giết


11

Tôi cần chạy một chương trình java trên các máy chủ của trường đại học. Tôi đang đăng nhập từ xa thông qua máy chủ của họ thông qua ssh

Vì vậy, tôi đã sử dụng nohup như vậy:

nohup java -jar project.jar &

Tuy nhiên, khi tôi đăng xuất và đóng thiết bị đầu cuối, sau đó đăng nhập lại vào máy chủ, quá trình của tôi bị thiếu / bị tắt.


Hãy thử chuyển hướng stdoutstderrđến một số tệp - quá trình của bạn có thể bị giết bởi tín hiệu khác ngoài SIGHUP, khi cố gắng ghi vào một thiết bị đầu cuối đóng stdout/ stderr. Ví dụ, thêm >/dev/null 2>&1vào lệnh của bạn trước khi &ký công việc.
Boris Burkov

1
@ Bob không nên cần thiết với nohup- hầu hết các trường sẽ thực hiện điều này theo mặc định mặc dù nó có thể cần thiết để chuyển hướng stdinví dụ </dev/null.
Graeme

Câu trả lời:


14

nohupchỉ làm cho chương trình miễn dịch SIGHUPSIGQUITtín hiệu. Shell hiện đại có thể gửi các tín hiệu khác khi bạn đăng xuất khỏi phiên của mình, vì vậy không có gì đảm bảo rằng chương trình của bạn không bị giết, thậm chí chạy theo nohup.

Giải pháp tốt hơn là sử dụng tmuxhoặc screen, hoặc nếu bạn sử dụng bash, bạn có thể thử:

$ java -jar project.jar &
$ disown

Nếu bạn sử dụng disown, bạn cần chuyển hướng thủ công, ví dụ: thêm</dev/null &>/dev/null
Graeme

@Graeme: Tôi nghĩ rằng nếu chúng ta không làm việc với shell nữa (chỉ cần chạy lệnh và thoát), thì không cần phải chuyển hướng.
cuonglm

Hãy thử ssh localhost 'sleep 10m & disown'. bashsẽ không thoát.
Graeme

Ok có vẻ như sshkhông thoát nếu có các chương trình được kết nối với thiết bị đầu cuối. Tuy nhiên, ở trên là tốt nếu bạn chạy tương tác.
Graeme

Các triển khai Linux (GNU coreutils và busybox) và BSD nohupkhông làm cho lệnh miễn nhiễm với SIGQUIT, mà chỉ để SIGHUP. Điều đó rõ ràng là trái với tiêu chuẩn và AFAIK chỉ có thể xảy ra trên (một số phiên bản?) Solaris.
mosvy

13

Một lựa chọn khác thay cho (rối loạn chức năng mãn tính) nohup:

setsid java -jar project.jar </dev/zero &>/dev/null &

Điều này có hiệu quả "daemonizes" quá trình. Hiện tại nó thuộc sở hữu của init, vì vậy sẽ không bao giờ có HUP, các luồng I / O của nó an toàn và nó đã bị rẽ vào nền.

Xem man setsidđể biết thêm thông tin. Không giống như screenhay tmux, đây không phải là một chương trình mà tuyên bố quyền sở hữu và tiếp tục chạy. Nó chỉ đơn giản là bắt đầu một chương trình trong nhóm quy trình riêng của mình .


Tại sao nohup rối loạn chức năng?
cpugeniusmv

@cpugeniusmv Tôi chắc chắn rằng nó tốt cho một cái gì đó, tuy nhiên, tôi không thấy nó đáng tin cậy cho mục đích mà nó thường được đề xuất, đăng nhập ở đâu đó, bắt đầu một quy trình và đăng xuất (giống như OP). Tôi đoán nó có thể đã bị lạm dụng, và có lẽ setsidlà một chút ngu ngốc hơn bằng chứng theo cách này. Nó bỏ qua một bước ngụ ý của nohup (có quá trình được phát minh lại bởi init như một đứa trẻ mồ côi). nohupsẽ linh hoạt hơn nếu bạn có khả năng muốn tiến hành công việc sau này.
goldilocks

@ TAFKA'goldilocks 'Tôi nghĩ vấn đề nằm ở việc xử lý stdin, stdout và stderr, điều này không thực sự (nhưng một phần (!)) Được xử lý bởi nohup. Nohup thực hiện công việc chính của nó khá tốt, che chắn quá trình từ SIGHUP. Nhưng có rất nhiều điều có thể sai với các luồng - hoặc, tệ hơn nhiều, đôi khi sai, tùy thuộc vào kích thước bộ đệm. Tôi nói, không phải nohup là sai, nhưng kỳ vọng những gì nohup làm.
Volker Siegel


-2

Hãy thử chạy nohup của bạn với chuyển hướng STDOUT và STDERR thành null:

nohup java -jar project.jar 2>&1 &

1
Bạn chỉ chuyển hướng stderr sang stdout, điều này không thay đổi bất cứ điều gì về cách thức hoạt động của nohup (nó chuyển hướng cả hai đến nohup.out).
Gilles 'SO- ngừng trở nên xấu xa'

1
-1, tôi nghĩ bạn có ý nohup java -jar project.jar 2>/dev/null &nhưng rõ ràng bạn không biết bạn đang làm gì. Thậm chí tốt hơn, cũng cho ăn stdin /dev/null.
PlasmaPower

@PlasmaPower ở đây bạn có +1 của bạn. Chúc một ngày tốt lành :)
boris quiroz
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.