Ai đó có thể giải thích chi tiết về những gì mà bộ Set -m không làm được không?


16

Trên trang người đàn ông , nó chỉ nói:

-m Kiểm soát công việc được bật.

Nhưng điều này thực sự có nghĩa là gì?

Tôi đã bắt gặp lệnh này trong một câu hỏi SO , tôi có cùng một vấn đề với OP, đó là "vải không thể bắt đầu tomcat". Và đã set -mgiải quyết điều này. OP giải thích một chút, nhưng tôi không hiểu lắm:

Vấn đề là ở các tác vụ nền vì chúng sẽ bị giết khi lệnh kết thúc.

Giải pháp rất đơn giản: chỉ cần thêm "set -m;" tiền tố trước lệnh.

Câu trả lời:


10

Trích dẫn tài liệu bash (từ man bash):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.

Vì vậy, khá đơn giản nói, có set -m(mặc định cho các hệ vỏ tương tác) cho phép một người sử dụng built-in như fgbg, trong đó sẽ bị vô hiệu hóa dưới set +m(mặc định cho vỏ không tương tác).

Tuy nhiên, đối với tôi, việc kết nối giữa kiểm soát công việc và giết các quá trình nền khi thoát ra không rõ ràng, nhưng tôi có thể xác nhận rằng có một: chạy set -m; (sleep 10 ; touch control-on) &sẽ tạo tệp nếu một người thoát khỏi trình bao ngay sau khi gõ lệnh đó, nhưng set +m; (sleep 10 ; touch control-off) &sẽ không.

Tôi nghĩ rằng câu trả lời nằm trong phần còn lại của tài liệu cho set -m:

-m      Monitor  mode. [...]                     Background pro‐
        cesses run in a separate process group and a  line  con‐
        taining  their exit status is printed upon their comple‐
        tion.

Điều này có nghĩa là các công việc nền được bắt đầu bên dưới set +mkhông phải là "quy trình nền" thực tế ("Các quy trình nền là những quy trình có ID nhóm quy trình khác với thiết bị đầu cuối"): chúng chia sẻ cùng một ID nhóm quy trình như trình bao khởi động chúng, thay vì có riêng nhóm quy trình như các quy trình nền thích hợp. Điều này giải thích hành vi được quan sát khi shell thoát ra trước một số công việc nền của nó: nếu tôi hiểu chính xác, khi thoát, tín hiệu được gửi đến các quy trình trong cùng nhóm quy trình với shell (do đó, giết chết các công việc nền bắt đầu theo set +m), nhưng không cho những nhóm của các nhóm quy trình khác (do đó để lại các quy trình nền thực sự bắt đầu bên dưới set -m).

Vì vậy, trong trường hợp của bạn, startup.shkịch bản có lẽ bắt đầu một công việc nền. Khi tập lệnh này được chạy không tương tác, chẳng hạn như qua SSH như trong câu hỏi bạn đã liên kết, kiểm soát công việc bị vô hiệu hóa, công việc "nền" chia sẻ nhóm quy trình của trình điều khiển từ xa và do đó sẽ bị giết ngay khi trình bao đó thoát ra. Ngược lại, bằng cách cho phép kiểm soát công việc trong lớp vỏ đó, công việc nền có được nhóm quy trình riêng của nó và không bị giết khi trình bao mẹ của nó thoát ra.


Thx cho câu trả lời của bạn, nhưng làm thế nào có tomcat/bin/startup.shliên quan đến fg/ bg?
laike9m

1
Nó không liên quan trực tiếp; Tôi đã cố gắng trả lời "Kiểm soát công việc được kích hoạt / điều này thực sự có nghĩa là gì?" Một cách tổng quát. Có lẽ tôi đã không nói rõ, nhưng kịch bản của bạn dường như bắt đầu một công việc nền, đó là những gì phần còn lại của câu trả lời của tôi áp dụng cho.
dhag

2

Tôi đã tìm thấy điều này trong danh sách vấn đề của github và tôi nghĩ rằng điều này thực sự trả lời câu hỏi của bạn.

Đây thực sự không phải là vấn đề SSH, đó là hành vi tinh tế hơn xung quanh các chế độ không tương tác / tương tác BASH và truyền tín hiệu đến các nhóm xử lý.

Việc theo dõi được dựa trên /programming/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774http: //www.itp.uzh.ch/~dpotter/howto/daemonize , với một số giả định chưa được xác thực đầy đủ, nhưng các thử nghiệm về cách thức hoạt động của nó dường như xác nhận.

pty / tty = sai

Shell bash được khởi chạy kết nối với thiết bị xuất chuẩn / stderr / stdin của quá trình bắt đầu và được tiếp tục chạy cho đến khi không có gì được gắn vào ổ cắm và trẻ em đã thoát. Một quy trình deamon tốt sẽ đảm bảo nó không đợi trẻ em thoát ra, rẽ nhánh một quy trình con rồi thoát. Khi ở chế độ này, SIGHUP sẽ không được gửi đến tiến trình con bằng SSH. Tôi tin rằng điều này sẽ hoạt động chính xác cho hầu hết các tập lệnh thực hiện một quy trình xử lý việc tự khử nhiễu và không cần phải được làm nền. Khi các tập lệnh init sử dụng '&' để làm nền cho một quy trình thì có khả năng vấn đề chính là liệu quy trình nền có từng cố đọc từ stdin hay không vì điều đó sẽ kích hoạt SIGHUP nếu phiên bị chấm dứt.

pty / tty = đúng *

Nếu tập lệnh init tạo nền cho quá trình bắt đầu, trình bao BASH cha sẽ trả lại mã thoát cho kết nối SSH, nó sẽ lần lượt tìm cách thoát ngay lập tức vì nó không chờ quá trình con kết thúc và không bị chặn trên thiết bị xuất chuẩn / stderr / stdin. Điều này sẽ khiến SIGHUP được gửi đến nhóm quy trình shell bash cha, do điều khiển công việc bị vô hiệu hóa trong chế độ không tương tác trong bash, sẽ bao gồm các tiến trình con vừa khởi chạy. Khi một quy trình daemon rõ ràng bắt đầu một phiên quy trình mới khi chuyển đổi hoặc trong quy trình rẽ nhánh thì nó sẽ không nhận được SIGHUP từ quy trình cha mẹ BASH. Lưu ý điều này khác với các công việc bị đình chỉ sẽ thấy một SIGTERM. Tôi nghi ngờ những vấn đề xung quanh việc này chỉ hoạt động đôi khi phải làm với một điều kiện chủng tộc nhẹ. http://www.itp.uzh.ch/~dpotter/howto/daemonize , bạn sẽ thấy rằng trong mã, phiên mới được tạo bởi quy trình rẽ nhánh có thể không được chạy trước khi thoát cha, do đó dẫn đến ngẫu nhiên hành vi thành công / thất bại được đề cập ở trên. Một tuyên bố về giấc ngủ sẽ cho phép đủ thời gian để quá trình rẽ nhánh tạo ra một phiên mới, đó là lý do tại sao nó hoạt động trong một số trường hợp.

pty / tty = true và kiểm soát công việc được bật rõ ràng trong bash

SSH sẽ không kết nối với stdout / stderr / stdin của bash shell hoặc bất kỳ tiến trình con đã khởi chạy nào, điều đó có nghĩa là nó sẽ thoát ngay khi shell bash cha bắt đầu thực hiện xong các lệnh được yêu cầu. Trong trường hợp này, với điều khiển công việc được bật rõ ràng, mọi quy trình được khởi chạy bởi bash shell với '&' để làm nền chúng sẽ được đặt vào một phiên riêng ngay lập tức và sẽ không nhận được tín hiệu SIGHUP khi quá trình cha mẹ đến phiên BASH thoát ( Kết nối SSH trong trường hợp này).

Những gì cần thiết để sửa chữa

Tôi nghĩ rằng các giải pháp chỉ cần được đề cập rõ ràng trong tài liệu hoạt động run / sudo như một trường hợp đặc biệt khi làm việc với các quy trình / dịch vụ nền. Về cơ bản, sử dụng 'pty = false' hoặc trong trường hợp không thể, rõ ràng cho phép kiểm soát công việc là lệnh đầu tiên và hành vi sẽ chính xác.

Từ https://github.com/foven/foven/issues/395

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.