Giết một quá trình bị đình chỉ?


17

Tôi hơi bối rối bởi:

% vim tmp
zsh: suspended   vim tmp
% kill %1
% jobs
[1]  + suspended   vim tmp
% kill -SIGINT %1
% jobs
[1]  + suspended   vim tmp
% kill -INT %1
% jobs
[1]  + suspended   vim tmp

Vì vậy, tôi đã từ chức để "tự làm" và tự hỏi tại sao sau này:

% fg
[1]  - continued   vim tmp
Vim: Caught deadly signal TERM
Vim: Finished.
zsh: terminated   vim tmp
%

Oh!

Thực sự có ý nghĩa, bây giờ tôi nghĩ về nó, nó vimphải được chạy để xử lý tín hiệu của nó được yêu cầu bỏ, và làm như vậy.

Nhưng rõ ràng không phải là những gì tôi dự định.

Có cách nào để "đánh thức và thoát" trong một lệnh không? tức là một bí danh tích hợp cho kill %N && fg %N?

Tại sao nối lại trong nền không hoạt động? Nếu tôi bgthay vì fg, Vim vẫn sống cho đến khi tôi fgphá vỡ trực giác của tôi.

Câu trả lời:


20

vi-vi-vilà của quỷ Bạn phải giết nó bằng lửa. Hoặc SIGKILL:

kill -KILL %1

Các nội dung killđủ tốt để gửi SIGCONTđến các quy trình bị treo để bạn không phải tự làm điều đó, nhưng điều đó sẽ không hữu ích nếu quy trình chặn tín hiệu bạn gửi hoặc nếu xử lý tín hiệu khiến các quy trình bị treo một lần nữa (nếu một quá trình nền cố gắng đọc từ thiết bị đầu cuối, theo mặc định, nó sẽ được gửi SIGTTIN, nó sẽ đình chỉ quá trình nếu không được xử lý).


1
Tại sao bạn lại sử dụng SIGABRT? Nó có nghĩa là để chỉ ra một lỗi chương trình. SIGKILL ở ngay đây vì bạn muốn giết chương trình ngay bây giờ dù muốn hay không.
Gilles 'SO- ngừng trở nên xấu xa

1
Trên thực tế, có vẻ như SIGTERMđánh thức các quá trình ngủ bây giờ, ít nhất là nếu họ không có người xử lý cho nó. Tôi nghĩ rằng nó đã không được sử dụng để làm việc theo cách này, vì tôi nhớ phải bghoặc fgmột cái gì đó trước khi nó sẽ nhận được tín hiệu và biến mất. Nhưng tôi đã thử nghiệm với awk 'BEGIN{while(42){}}' &, và strace kill $!, chỉ có một kill(2)cuộc gọi hệ thống, với SIGTERM.
Peter Cordes

6

vimđang cài đặt trình xử lý tín hiệu (và có thể cũng cài đặt sigprocmask(2)) để bỏ qua các tín hiệu phổ biến để mọi tệp đang được chỉnh sửa không bị mất do điều khiển đi lạc + c hoặc tín hiệu tắt ngẫu nhiên. Một chương trình đơn giản hơn dễ dàng bị giết:

% cat busyloop.c
int main(void) {
for (;;) { ; }
return 0;
}
% make busyloop
cc     busyloop.c  -o busyloop
% ./busyloop
^Z
zsh: suspended  ./busyloop
% kill %1
%
[1]  + terminated  ./busyloop

Thực hiện vimthoát (an toàn) sẽ yêu cầu một trình xử lý tín hiệu trong vimđó chấp nhận TERMhoặc USR1hoặc một cái gì đó, lưu (hoặc loại bỏ?) Bất kỳ bộ đệm, v.v. Bạn đang cố gắng làm gì để thực hiện vimthoát như thế này?


"Bạn đang cố gắng làm gì để khiến vim thoát như thế này?" - không có gì, đó là một tập tin "tmp" thực sự mà tôi đang chỉnh sửa. vimchỉ là một sự lựa chọn sai lầm của chương trình để kiểm tra đình chỉ.
OJFord

1
"bỏ qua các tín hiệu phổ biến để mọi tập tin đang được chỉnh sửa không bị mất do điều khiển đi lạc + c hoặc tín hiệu tiêu diệt ngẫu nhiên" - nhưng ngay sau khi tôi fgthoát ra, nó chỉ dừng lại chừng nào nó bị treo?
OJFord

2
@OllieFord: Chỉ SIGKILLđánh thức một quá trình ngủ để nó có thể chết. Gửi tín hiệu đến một quy trình bị treo có trình xử lý tùy chỉnh cho chúng không đánh thức nó. (Tất nhiên SIGCONT, ngoài tín hiệu tiếp tục, tất nhiên. bgfggửi SIGCONT.)
Peter Cordes
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.