Kết thúc một quá trình trong Unix thay vì làm gián đoạn nó


12

Tại Unixdòng lệnh nếu tôi nhấn Ctrl-C, điều đó không kết thúc một quá trình, mà là làm gián đoạn nó và tôi quay lại dấu nhắc shell.

Vì vậy, tôi có hai câu hỏi sau đây:

    1. Có cách nào tôi có thể xem danh sách tất cả các quá trình bị gián đoạn và kết thúc chúng không?
    1. Tổ hợp phím nào để nhấn để kết thúc một quá trình thay vì làm gián đoạn nó?

Câu trả lời:


20

Ctrl+ Cgửi a SIGINT. Theo mặc định, điều này chấm dứt ứng dụng.

Bạn đang nhầm lẫn điều này với Ctrl-Z, trong đó đình chỉ một ứng dụng trong bash.


7

Trong lịch sử có ba tín hiệu bị ràng buộc với tổ hợp phím này là

  • SIGINT (Intettput) thường Ctrl+ ChoặcDel
  • SIGQUIT - Thoát - Thường bị ràng buộc với Ctrl+\
  • Tạm dừng SIGSUSP - Thường bị ràng buộc với Ctrl+Z

Trên một số hương vị * nix có các tín hiệu khác cũng bị ràng buộc, bạn có thể kiểm tra các ràng buộc bàn phím bằng lệnh

stty -a

Trên hệ thống của tôi, OS / X, điều này tạo ra đầu ra sau

speed 9600 baud; 65 rows; 213 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

Xin lưu ý kill trong trường hợp này không phải là tín hiệu KILL mà nó phải làm với việc xóa bộ đệm đầu vào hiện tại.

Bạn có thể thành công hơn với việc dừng các quy trình bằng SIGQUIT, nhưng điều này có thể không đúng vì quy trình có thể bắt được tín hiệu và bỏ qua nó.

Không có khái niệm về danh sách các quá trình "bị gián đoạn" vì quá trình này đã bị bắt và bỏ qua ngắt hoặc nó đã thoát. Bạn có thể nhận được một danh sách các quy trình bị đình chỉ bằng cách gõ công việc


Thật thú vị khi tôi có ^ Q và ^ S hiển thị (như bạn) nhưng đã thiết lập stty -ixonđể chúng được truyền qua. Tôi nghĩ họ sẽ thay đổi <undef>.
Tạm dừng cho đến khi có thông báo mới.

Tôi không tìm thấy SIGSUSP trong các trang man của hộp OS X hoặc hộp Debian Lenny của tôi. Nó dường như là SIGTSTP.
dmckee --- ex-moderator mèo con

DEL - ah, Kế hoạch 9 ...
new123456

5

Rất nhiều câu trả lời đúng, nhưng không có câu trả lời nào hoàn chỉnh.

  1. Như nhiều người khác đã nói: Control-C thường gửi tín hiệu unix SIGINT và hành vi mặc định (từ các chương trình không ghi đè lên nó) là "quá trình chấm dứt". Chương trình có thể bỏ qua tín hiệu này hoặc thực hiện một hành động khác nếu muốn.
  2. Bạn cũng có thể gửi SIGQUIT từ bàn phím bằng Control- \. Sự khác biệt ở đây là theo mặc định, quá trình sẽ ghi một tệp lõi, sau đó thoát. Chương trình có thể bỏ qua tín hiệu này hoặc thực hiện một hành động khác nếu muốn.
  3. Để chấm dứt với định kiến ​​cực đoan và không cho phép quá trình dừng bạn sử dụng SIGKILL, vốn không bị ràng buộc với bất kỳ khóa nào theo mặc định. Thay vào đó, bạn thường gửi nó bằng kill (1)lệnh và chỉ định tín hiệu để gửi như trong

    $ kill -9 <process ID>
    

    hoặc thường xuyên

    $ kill -KILL <process ID>
    

    Tín hiệu này được HĐH xử lý trực tiếp và chương trình không thể ghi đè hành vi mặc định.

  4. Nếu shell của bạn hỗ trợ kiểm soát công việc, nó cũng có thể hỗ trợ phiên bản tích killhợp hỗ trợ nhận dạng công việc bằng cách sử dụng %ký tự như trong câu trả lời của sàn catwalk .

  5. Để tạm dừng một quy trình theo cách có thể tiếp tục, bạn sử dụng Control-z gửi SIGTSTP. Bạn tiếp tục quá trình như vậy fgđể tiếp tục kiểm soát thiết bị đầu cuối hoặc bgđể thiết bị chạy mà không giữ quyền kiểm soát thiết bị đầu cuối (nhưng theo mặc định, vẫn gửi đầu ra của nó ở đó).

Ngoài ra, việc bán phá giá lõi trên SIGQUIT phụ thuộc vào nhiều chi tiết hành chính. ulimit -c, coreadm (1M) trên Solaris, v.v. Một lưu ý khác - fg gửi tín hiệu SIGCONT, làm cho quá trình tiếp tục hoạt động.
Tadeusz A. Kadłubowski

1
  1. để xem danh sách các quá trình nền: jobs

    để giết: kill %1(thay thế 1 bằng id công việc tương ứng như ở jobsđầu ra)

  2. xem ở đây

1

Ctrl-C gửi SIGINT, theo mặc định sẽ khiến một quá trình kết thúc, nhưng có thể bị mắc kẹt (trong \bin sh, sử dụng trap).

SIGKILL là tín hiệu tiêu diệt không thể phá vỡ.

Chỉnh sửa Lần thứ ba, tôi nghĩ điều này đúng: Tôi đã kiểm tra mọi thứ đối với các tài liệu. Chúng ta sẽ thấy.


SIGKILL không phải là bẫy.

Vâng. Tôi đã sửa nó ...
Charles Stewart

1

Điều này không rõ ràng với hầu hết những người mới sử dụng thiết bị đầu cuối, nhưng nếu vấn đề của bạn chỉ là bạn đang ở trong một chương trình tương tác và bạn không thể tìm ra cách thoát ra, thì thường qsẽ thoát ra. Ví dụ, đây là chìa khóa để thoát less, đây cũng là chương trình bạn nhận được khi xem mancác trang, trong số những thứ khác.

Một số chương trình có các phím tắt khác để thoát. Trong vimhoặc vi, sử dụng ESC:wq. Trong emacs, sử dụng Control-C Control-X. Trong nanohoặc pico, sử dụng Control-X. Lưu ý rằng trong các ví dụ này, có sự tinh tế, đặc biệt, liên quan đến việc các phím tắt đó có lưu bất kỳ thay đổi nào bạn có thể thực hiện đối với tệp bạn đang chỉnh sửa hay không.


Vậy tiêu chuẩn là gì?
Pacerier

0

Nhiều quy trình có thể cài đặt trình xử lý ngắt để bắt tín hiệu ngắt, nhưng các quy trình không hủy bỏ theo mặc định.

Để buộc một quá trình thoát, bạn có thể gửi SIGQUIT (Ctrl- \).


SIGQUIT có thể bị mắc kẹt, SIGKILL không thể.
Charles Stewart

1
@Charles: một sự khác biệt khác là SIGQUIT bỏ lõi theo mặc định, SIGKILL không.
Tadeusz A. Kadłubowski

0

Có vẻ như các câu trả lời khác là kịch bản có khả năng, nhưng cũng có thể là bạn đang thực thi một tập lệnh không xử lý chính xác các phần tử con của nó. Gần đây tôi đã gặp một kịch bản tương tự, trong đó việc giết một tập lệnh sẽ không giết chết các tiến trình con của tập lệnh đó.

Nói chung, nếu bạn gặp phải tình huống này, bạn sẽ phải xem lại tất cả các quy trình mà bạn đang chạy. Bạn nên xem lại manpage cho ps. ( man ps) Tôi đặc biệt thích sử dụng ps auxwf, trong đó cho thấy mối quan hệ cha / con giữa các quy trình. pstreelàm một cái gì đó tương tự. Bạn nên chạy cái này từ một thiết bị đầu cuối khác trước khi giết quá trình để xem mọi thứ trông như thế nào trong tình huống bình thường và xác định các quy trình con.

Nếu sau đó bạn giết (với ^ C) quá trình chính đó, hãy kiểm tra lại đầu ra của ps để xem có gì thay đổi không. Nếu các tiến trình con vẫn ở xung quanh, bạn có thể giết chúng bằng killlệnh. (xem man kill)

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.