Как я могу использовать cron для планирования сценария, который реализует переход на летнее время в приложениях, не поддерживающих DST, когда мой сервер автоматически использует DST?

Мой сервер (на котором работает сервер Ubuntu 8.04LTS) прямо сейчас сообщает о времени 9:38 вечера BST. BST (британское летнее время) на 1 час опережает UTC (или среднее время по Гринвичу, если вы действительно хотите запутать вопросы)

Акт парламента определяет, что мы в Великобритании используем BST для

период, начинающийся в час по среднему времени по Гринвичу, утром последнего воскресенья марта и заканчивающийся в час по среднему времени по Гринвичу, утром последнего воскресенья октября.

Нет проблем с расписанием в cron, но я не знаю, какой формат даты / часовой пояс мне следует использовать. Должен ли я установить его для продвижения вперед в 1:00, но обратно в 2:00, когда он заканчивается? Это имеет смысл, если машина использует BST, но я беспокоюсь, что этот хрон не сработает в 2 часа ночи, потому что системные часы могут быть сброшены назад до 1 часа ночи, прежде чем у него появится шанс на запуск - таким образом, мой скрипт запустится на 1 час позже.

Или он просто использует UTC?

2 ответа

Решение

Ответ лежит в источниках cron (которые вы можете получить, apt-get source cron), особенно в основном цикле в строках 159-272 файла cron.c,

crond спит в течение минуты, затем просыпается и запрашивает системное время, сравнивая его с его собственным представлением о времени (то есть, какое время это было бы, если бы ничто не изменило часы). Основываясь на разнице между фактическим и ожидаемым временем, crond принимает разные действия; два из них актуальны в вашем случае:

  1. Время прыгнуло вперед более чем на 5 минут, но менее чем на 3 часа (запускается летнее время): cron запускает задания с подстановочными знаками, запланированные в фактическое время, и любые задания, запланированные в фиксированное время между вычисленным временем и фактическим временем. Соответствующий источник в строках 221-247:

      /*
       * case 2: timeDiff is a medium-sized positive number,
       * for example because we went to DST run wildcard
       * jobs once, then run any fixed-time jobs that would
       * otherwise be skipped if we use up our minute
       * (possible, if there are a lot of jobs to run) go
       * around the loop again so that wildcard jobs have
       * a chance to run, and we do our housekeeping
       */
      Debug(DSCH, ("[%d], DST begins %d minutes to go\n",
          getpid(), timeRunning - virtualTime))
      /* run wildcard jobs for current minute */
      find_jobs(timeRunning, &database, TRUE, FALSE);
    
    
      /* run fixed-time jobs for each minute missed */ 
      do {
         if (job_runqueue())
                 sleep(10);
         virtualTime++;
         find_jobs(virtualTime, &database, FALSE, TRUE);
         set_time();
      } while (virtualTime< timeRunning &&
          clockTime == timeRunning);
      break;
    
  2. Время ушло назад менее чем на 3 часа (DST заканчивается): просто запустите подстановочные задания, пропустите задания с фиксированным расписанием, так как они уже запущены. Соответствующий источник в строках 247-258:

    /*
     * case 3: timeDiff is a small or medium-sized
     * negative num, eg. because of DST ending just run
     * the wildcard jobs. The fixed-time jobs probably
     * have already run, and should not be repeated
     * virtual time does not change until we are caught up
     */
    Debug(DSCH, ("[%d], DST ends %d minutes to go\n",
        getpid(), virtualTime - timeRunning))
    find_jobs(timeRunning, &database, TRUE, FALSE);
    break;
    

Таким образом, при вводе DST у вас не должно возникнуть проблем: ваш скрипт будет запущен (либо непосредственно, либо сразу после скачка времени).

При выходе из DST существует риск того, что ваша (фиксированная) работа будет пропущена, если вы запланируете ее точно на 1 час. Мое предложение было бы запланировать запуск либо за 1 минуту до 1 часа, либо в 2 часа (или после).

Вы можете попробовать переключить UTC=no если это yes или наоборот в /etc/default/rcS, Для этого запустите:

gksu gedit /etc/default/rcS
  • + Изменить UTC=no в UTC=yesили
  • + Изменить UTC=yes в UTC=no,

Сохраните файл, выйдите из текстового редактора и перезагрузите компьютер.

Другие вопросы по тегам