Убить приостановленный процесс?

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сломаю мою интуицию.

OJFord
источник

Ответы:

20

vi-vi-viэто от дьявола. Вы должны убить его огнем. Или SIGKILL:

kill -KILL %1

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

PSkocik
источник
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выход таким, как этот?

thrig
источник
"Что ты пытаешься сделать, чтобы заставить Vim выйти таким образом?" - ничего, это был действительно "tmp" файл, который я редактировал. vimбыл просто непродуманный выбор программы для проверки подвески.
OJFord
1
«игнорировать общие сигналы, чтобы редактируемые файлы не терялись из-за случайного управления + c или случайного сигнала уничтожения», - но как только я fgвышел, он остановился только на время приостановки?
OJFord
2
@OllieFord: только SIGKILLпробуждает процесс сна, чтобы он мог умереть. Отправка сигналов в приостановленный процесс, который имеет собственные обработчики для них, не пробуждает его. (Кроме SIGCONTсигнала продолжения, конечно. bgИ fgотправить SIGCONT.)
Питер Кордес