1

На Fedora 17 я поместил файл в /etc/cron.daily со следующим содержимым:

cd /
su dstahlke /home/dstahlke/bin/anacron-daily.sh
exit 0

По какой-то причине я получаю почту каждый день, в которой просто говорится

/etc/cron.daily/dstahlke-daily:

 ...killed.

Я попытался с и без строки exit 0 выше (я заметил, что некоторые системные скрипты имеют это, а другие нет, я не уверен в цели). Запуск /etc/cron.daily/dstahlke-daily из командной строки с правами root не приводит к ...killed сообщению. Кроме сообщения, все, кажется, работает нормально. Помещение set -x в приведенный выше скрипт, а также в скрипт /home/dstahlke/bin/anacron-daily.sh показывает, что сообщение ...killed kill происходит сразу после завершения последнего скрипта (или, возможно, сразу после команды su отделки).

Что вызывает ...killed сообщение?

Или есть более приемлемый способ, чтобы anacron ежедневно запускал пользовательский скрипт? Я подумал, что размещение этого в /etc/cron.daily поможет системе скоординировать все ежедневные задачи, а не потенциально выполнять мою задачу одновременно с системными задачами.

1 ответ1

2

Я провел дальнейшее расследование и обнаружил, что ...killed действительно печатается программой su , хотя печать не идет из проекта coreutils из основной ветки разработки, она вводится coreutils-8.5-pam.patch в исходную версию rpm. Существует некоторая история о происхождении добавления этого в bugzilla (622700 , 597928 и 240117).

Соответствующая часть кода

static sig_atomic_t volatile caught_signal = false;
...
/* Signal handler for parent process.  */
static void
su_catch_sig (int sig)
{
  caught_signal = true;
}

...

static void
create_watching_parent (void)
{
  ...
  sigfillset (&ourset);
  if (sigprocmask (SIG_BLOCK, &ourset, NULL))
    {
      error (0, errno, _("cannot block signals"));
      caught_signal = true;
    }
  if (!caught_signal)
    {
       ...
       action.sa_handler = su_catch_sig;
       ...
         || sigaction (SIGTERM, &action, NULL)
 ...
  if (caught_signal)
    {
      fprintf (stderr, _("\nSession terminated, killing shell..."));
      kill (child, SIGTERM);
    }

  cleanup_pam (PAM_SUCCESS);

  if (caught_signal)
    {
      sleep (2);
      kill (child, SIGKILL);
      fprintf (stderr, _(" ...killed.\n"));
    }
  exit (status);
}

Таким образом, в некотором роде (прямо или косвенно связанный с cleanup_pam или не связанным) родительский процесс получает SIGTERM между вторым последним и последним тестами if и, таким образом, печатает только сообщение ...killed которое, очевидно, должно было быть продолжением fprintf. выше.

В общем, двойное использование caught_signal как средства обработки асинхронного сигнала и как локальной переменной управления потоком внутри функции выглядит как очень грязный хак, и мне не понравился код. Я проверил это, разделив его, и ввел логическую переменную kill_child для использования в теле функции, а затем

  if (caught_signal)
    {
kill_child:
      kill_child = true;
      status = 1;
    }

  if (kill_child) {
    {
      fprintf (stderr, _("\nSession terminated, killing shell..."));
      kill (child, SIGTERM);
    }

  cleanup_pam (PAM_SUCCESS);

  if (kill_child)
    {
      sleep (2);
      kill (child, SIGKILL);
      fprintf (stderr, _(" ...killed.\n"));
    }
  exit (status);
}

в конце функции. С этой модификацией я больше не получаю ....killed спам от анакрона.


Так что длинное объяснение и, возможно, больше информации, чем вам нужно. Тем не мение. Я также узнал еще кое-что, что является хорошей новостью для вас, поскольку вам не нужно вносить локальные изменения в пакет coreutils. В таких случаях, как запуск su из cron, вы должны вместо этого запустить программу runuser. Это своего рода "плохие" новости для меня, так как это делает мои выводы менее важными, но хорошо :).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .