Назад | Перейти на главную страницу

Ctrl + c не работает для некоторых приложений в Linux

Это действительно странная проблема, но в новых системах (Fedora, Ubuntu) ctrl + c не влияет на некоторые инструменты:

если я выполняю список yum, который работает почти минуту, я не могу прервать запуск с помощью ctrl + c

$time yum list >/dev/null
^C^C^C^C^C^C^C^C^C

Выполнение команды не прекращается.

Однако прервать поиск можно.

$ time find / >/dev/null 2>&1
^C

real    0m0.741s
user    0m0.033s
sys     0m0.124s

Мне любопытно, что вызывает это.

У меня следующие настройки:

$ stty -a
speed 38400 baud; rows 36; columns 158; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

Я пока не смог найти описание проблемы, буду благодарен, если кто-нибудь сможет пролить свет.

Заранее спасибо.

Ловушка некоторых приложений SIGINT из-за странного взаимодействия с другими библиотеками. Вы можете попробовать отправить им SIGQUIT вместо этого (через Ctrl\ как дано вашим stty вывод).

Некоторые приложения просто ловят SIGINT как упоминал Игнасио, другие захватывают весь ввод с клавиатуры.

Если C-c не работает, вы можете попробовать уже упомянутый C- \, а если это не сработает, просто попробуйте фоновый процесс: C-z. а затем убить его kill -s SIGKILL <pid>

Определенно связано с обработкой сигналов в команде, которую вы вызываете. Обратите внимание на ряд открытых ошибок yum, связанных с обработкой:

Red Hat Bugzilla - Список ошибок

https://bugzilla.redhat.com/buglist.cgi?quicksearch=yum+Ctrl-C

Похоже, Ctrl-C (SIGINT) могло быть использовано для управления другим поведением (переход к следующему зеркалу), а не обычным намерением (уничтожение процесса).

Re: почему SIGQUIT похоже, не делает ничего полезного - может не быть определенного обработчика.

Это ням-ошибка. Кажется, что все больше и больше разработчиков Linux думают, что было бы неплохо игнорировать стандартную обработку сигналов и заставить свое приложение не реагировать на стандартные сигналы.

человек 7 сигнал

   Standard Signals
       Linux  supports the standard signals listed below.  Several signal numbers are architecture-dependent, as indicated in the "Value" col-
       umn.  (Where three values are given, the first one is usually valid for alpha and sparc, the middle one for ix86, ia64, ppc, s390,  arm
       and sh, and the last one for mips.  A - denotes that a signal is absent on the corresponding architecture.)

       First the signals described in the original POSIX.1-1990 standard.

       Signal     Value     Action   Comment
       ----------------------------------------------------------------------
       SIGHUP        1       Term    Hangup detected on controlling terminal
                                     or death of controlling process
       SIGINT        2       Term    Interrupt from keyboard
       SIGQUIT       3       Core    Quit from keyboard
       SIGILL        4       Core    Illegal Instruction
       SIGABRT       6       Core    Abort signal from abort(3)
       SIGFPE        8       Core    Floating point exception
       SIGKILL       9       Term    Kill signal
       SIGSEGV      11       Core    Invalid memory reference
       SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                     readers
       SIGALRM      14       Term    Timer signal from alarm(2)
       SIGTERM      15       Term    Termination signal
       SIGUSR1   30,10,16    Term    User-defined signal 1
       SIGUSR2   31,12,17    Term    User-defined signal 2
       SIGCHLD   20,17,18    Ign     Child stopped or terminated
       SIGCONT   19,18,25    Cont    Continue if stopped
       SIGSTOP   17,19,23    Stop    Stop process
       SIGTSTP   18,20,24    Stop    Stop typed at tty
       SIGTTIN   21,21,26    Stop    tty input for background process
       SIGTTOU   22,22,27    Stop    tty output for background process

Это дурная привычка.

Обычно это происходит, когда приложение находится в состоянии, когда оно фактически не может отвечать на сигналы, потому что оно не может возобновить работу из очереди планировщика ЦП. Хороший пример - когда приложение зависает в ожидании операции блокировки (синхронный дисковый ввод-вывод в основном потоке, подкачка / выгрузка, блокировка сетевого ввода-вывода и т. Д.). Учитывая, что это ням, я предполагаю, что истекает время ожидания подключения к одному или нескольким источникам, определенным в конфигурациях вашего репозитория / зеркального списка, но это может быть проблема с дисковым вводом-выводом при доступе к его кешам, базе данных RPM (включая повреждение BDB) или любое количество других вещей.

Хороший способ проверить это поведение с любым произвольным приложением: жестко смонтировать общий ресурс NFS, затем отключить сервер NFS, затем попытаться использовать любую программу, которая пытается открыть этот каталог (хорошие примеры - find или / bin / ls). Он не будет реагировать ни на что, кроме SIGKILL, пока он ждет, пока ядро ​​выяснит, что случилось с общим ресурсом.

Фактически, rpmlib, используемый yum, захватывает и игнорирует обработчик сигнала ctrl-c. На уровне yum можно сделать очень многое. Это раздражает, но я не уверен, что стоит так сильно волноваться. Все новые и новые версии Fedora успешно улучшили обработку этого, до такой степени, что yum под Rawhide (который станет F15) сделает это для вашего тестового примера:

$ time yum list >/dev/null
^CTraceback (most recent call last):
  File "/usr/lib64/python2.7/site.py", line 553, in <module>
    main()
  File "/usr/lib64/python2.7/site.py", line 544, in main
    execsitecustomize()
  File "/usr/lib64/python2.7/site.py", line 500, in execsitecustomize
    import sitecustomize
KeyboardInterrupt

real    0m0.164s
user    0m0.081s
sys     0m0.073s

Он по-прежнему не позволит вам прерывать изменения в базе данных RPM с помощью SIGINT, с чем действительно трудно поспорить.