Вбити призупинений процес?


17

Мене трохи збентежили:

% 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

Тож я пішов у відставку, щоб просто "зробити це сам" і задаюся питанням, чому пізніше:

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

Ой!

Має сенс насправді, тепер, коли я замислююсь над цим, це vimповинно працювати, для того, щоб його обробник сигналу повинен був сказати вийти, і зробити це.

Але очевидно не те, що я задумав.

Чи є спосіб "прокинутися і кинути" в одній команді? тобто вбудований псевдонім для kill %N && fg %N?

Чому відновлення у фоновому режимі не працює? Якщо я bgзамість цього fg, Вім залишається живим, поки я fgне зламаю мою вище інтуїцію.

Відповіді:


20

vi-vi-viвід диявола. Ви повинні його вбити вогнем. Або SIGKILL:

kill -KILL %1

Вбудовані файли killдосить люб'язні для надсилання SIGCONTпризупинених процесів, щоб вам не довелося робити це самостійно, але це не допоможе, якщо процес блокує сигнал, який ви надсилаєте, або якщо обробка сигналу спричиняє призупинення процесів знову (якщо фоновий процес намагається прочитати з терміналу, за замовчуванням він буде надісланий SIGTTIN, який призупиняє процес, якщо не обробляється).


1
Чому б на Землі ви використовували SIGABRT? Це призначено для позначення програмної помилки. SIGKILL зараз тут, оскільки ви хочете вбити програму зараз, хоче вона чи ні.
Жиль "ТАК - перестань бути злим"

1
Насправді це схоже на те, що зараз SIGTERMпрокидається сплячі процеси, принаймні, якщо вони не мають для цього обробників. Я думаю, це не працювало таким чином, оскільки я пам’ятаю, що потрібно було bgчи fgщось робити, перш ніж він отримав би сигнал і пішов геть. Але я перевірив awk 'BEGIN{while(42){}}' &, і strace kill $!, і є лише один kill(2)системний виклик, з SIGTERM.
Пітер Кордес

6

vimвстановлює обробники сигналів (і, мабуть, також налаштовують sigprocmask(2)), щоб ігнорувати загальні сигнали, щоб жодні редаговані файли не втрачалися через відключений контроль + c або випадковий сигнал вбивства. Простіша програма легко вбивається:

% 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

Здійснення vimвиходу (безпечно) потребує обробника сигналу, vimякий приймаєTERM чи що- USR1небудь, зберігає (або відкидає?) Будь-які буфери тощо. Що ви намагаєтесь зробити, щоб зробити такий vimвихід таким?


"Що ви намагаєтесь зробити, щоб зробити так, щоб вихід вийшов таким?" - нічого, я редагував справді "tmp" файл. vimбув просто непродуманим вибором програми для перевірки припинення роботи.
OJFord

1
"ігноруйте загальні сигнали, щоб жодні файли, що редагуються, не втрачалися через заблокований контроль + c або випадковий сигнал вбивства" - але як тільки я fgвийшов, він зупинився лише до тих пір, поки він був призупинений?
OJFord

2
@OllieFord: Лише SIGKILLпрокидається процес сну, щоб він міг померти. Передача сигналів в підвішеному процес , який має свої обробник для них це НЕ будити його. (Крім іншого SIGCONT, сигнал продовження, звичайно, bgі fgнадішліть SIGCONT.)
Пітер Кордес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.