Почему "Выполнение exit 130 не то же самое, что смерть от SIGINT"?

Осиротевший индексный дескриптор - это индексный дескриптор, который не прикреплен к записи каталога в файловой системе, что означает, что он недоступен.

Осиротевшие inodes могут появляться по ряду причин:

  • временные файлы, которые удаляются, но остаются открытыми (обычная практика), занимают inodes в файловой системе; если система перезагружается без надлежащего завершения работы, эти inodes остаются и становятся бесхозными
  • повреждение файловой системы может повредить каталог, не затрагивая inodes файлов, содержащихся в каталоге; эти inodes затем становятся потерянными

fsck создает новые записи каталога для потерянных inodes в lost + found .

3
19.08.2017, 00:13
1 ответ

130 (128+SIGINT ), которые вы видите в $?после того, как последняя команда умерла от SIGINT, является упрощенным представлением ее статуса выхода, сделанным некоторыми оболочками, такими как bash. Другие оболочки будут использовать другие представления (, такие как 256+signum в ksh93, 128+256+signum в yash, текстовые представления, такие как sigintили sigquit+coreв rc/es). См. Код выхода по умолчанию при завершении процесса? для получения более подробной информации об этом.

Процесс может ждать своего дочернего процесса и запрашивать его статус:

  • если он был остановлен (каким сигналом)
  • если оно было возобновлено
  • если убили (каким сигналом)
  • если у него есть захваченные(для ptrace d процессы)
  • если сбросил ядро ​​
  • , если он завершился нормально с _exit()системным вызовом (, с каким кодом выхода)

Для этого они используют один из wait(), waitpid(),waitid()(см. также устаревшие wait3(),wait4())или обработчик системного вызова SIGCHLD.

Эти системные вызовы возвращают всю указанную выше информацию. (За исключением waitid()в некоторых системах, только младшие 8 битов числа, переданного в _exit()для дочернего процесса, который завершается нормально, доступны, хотя ).

Ноbash(и большинство Bourne -подобных и csh -подобных оболочек )объединяют всю эту информацию в 8-битном числе, поскольку$?($?— это младшие 8 бит кода выхода для завершающихся процессов. нормально, а 128+signum его убили или подвесили или поймали,вся остальная информация недоступна ). Очевидно, что какая-то информация теряется. В частности, только по $?нельзя сказать, совершил ли процесс _exit(130)или умер из-за SIGINT.

bashочевидно знает, когда процесс уничтожается. Например, когда фоновые процессы убиты, вы видите:

[1]+  Interrupt               sleep 20

Но в $?это не дает вам достаточно информации, чтобы сказать, было ли оно убито SIGINT или вызвано _exit(130).

Поскольку большинство оболочек выполняют это преобразование, приложения лучше знают, чем делать _exit(number_greater_than_127)для чего угодно, кроме сообщения о смерти по сигналу.

Тем не менее, если процесс выполняет _exit(130), процесс, ожидающий этого процесса, обнаружит, что этот процесс завершился нормально, а не что он был уничтожен сигналом. В C WIFEXITED()вернет true , WIFSIGNALED()вернет false.

bashсам по себе не будет считать процесс умершим из-за SIGINT (, даже если он позволяет вам думать, что он может иметь сквозное $?, содержащее то же значение, как если бы он умер из-за SIGINT ).

Таким образом, это не вызовет специальной обработки SIGINT, которую вызывает bash. В сценарии и bash, и текущая команда в сценарии получат SIGINT после ^C(, так как они оба находятся в одной группе процессов ).

bashумирает при получении SIGINT, только если команда, которую он ожидает, также умерла из-за SIGINT (идея заключается в том, что если, например, в вашем скрипте вы запускаете vi или меньше и используете ^C, чтобы прервать что-то там, что не t заставит vi/ lessумереть, ваш скрипт не умрет после выхода из vi/ lessпозже ).

Если эта команда bashожидает выполнения _exit(130)в обработчике SIGINT, bashне умрет после этого SIGINT (она не будет считать себя прерванной, потому что не верит ребенок был прерван ).

Вот почему, когда вы хотите сообщить о смерти от SIGINT , что вы действительно были прерваны, хотя на самом деле вы выполняете дополнительную обработку при получении этого сигнала в обработчике , вы не должны делать _exit(130), а фактически убить себя с помощью SIGINT (после восстановления обработчика по умолчанию для SIGINT ). В скорлупе это с:

trap '
  extra processing
  trap - INT # restore SIGINT handler
  kill -s INT "$$" # report to the parent that we have indeed been
                   # interrupted
  ' INT
13
27.01.2020, 21:12

Теги

Похожие вопросы