Узнайте изнутри ID "на" работу
Когда я планирую работу с 'at', ей присваивается идентификатор, а именно:
работа 44 на 2014-01-28 17:30
Когда эта работа запускается, я хотел бы получить этот идентификатор изнутри. Это на Centos, FWIW. Я установил, что ни одна переменная среды не содержит идентификатор. Когда Perl-код в этом задании выполняется, я бы хотел, чтобы он мог напечатать идентификатор задания (44 в этом примере).
Да, я знаю, что atq показывает = рядом с выполняющимися заданиями, но может быть более одного из них одновременно.
Я мог бы сделать что-то вроде передачи уникального аргумента заданию при планировании, захвата идентификатора, сохранения этого и аргумента в файл где-нибудь, считывания этого из задания. Это большая работа, которую я бы предпочел не делать, если мне не нужно, и кажется, что это должно быть просто, но я рисую пробел.
1 ответ
Что следует, выясняется при чтении источников в-3.14. Способ размещения идентификатора задания и время его запуска в имени файла должны быть одинаковыми для любой версии, но я не проверял это.
Начнем с того, что кодирует идентификатор задания и время, когда конкретное задание должно быть запущено в имени файла, описывающего задание. Имя файла имеет формат aJJJJJTTTTTTTT
, где JJJJJ
является шестнадцатеричной строкой из 5 символов, идентификатором задания и TTTTTTTT
представляет собой шестнадцатеричную строку из 8 символов - время запуска задания. Время хранится в секундах от эпохи.
На заданиях выполняются путем подачи файла описания задания в качестве стандартного ввода в sh -c
, К счастью, ядро Linux предоставляет символическую ссылку, /proc/self/fd/0
, который будет указывать на стандартный ввод выполняемого в данный момент процесса (поиграйте с ls -l /proc/self/fd/0
на случай, если вам нужно убедиться, что это действительно так).
Файл, описывающий задание, был удален к моменту запуска задания. Тем не менее, файл все еще доступен для ядра, потому что он был дублирован с dup(2)
перед использованием в качестве стандартного ввода для работы. Итак, на самом деле мы разрешаем символическую ссылку на имя файла, которое больше не видно. В конце сценария Perl мы должны принять это во внимание как readlink
вернет что-то вроде /foo/bar/baz (deleted)
вместо /foo/bar/baz
, И нас интересует только имя файла, в котором есть вся необходимая информация.
Причина, по которой символическая ссылка указывает на удаленный файл, заключается в том, что демон демонтирует оригинал перед выполнением задания. Отмена ссылки выполняется только после создания копии, жесткой ссылки, которая начинается с =
вместо a
, Таким образом at at пытается убедиться, что будет запущена только одна копия задания: демон не будет execle(2)
т.е. это выручит, если link(2)
потерпеть поражение. Поскольку исходный файл был предметом open(2)
а также dup(2)
ядро все еще там для использования ядром, потому что оно все еще имеет жесткие ссылки, указывающие на него.
После довольно длинного и, возможно, запутанного введения, вот как все это собрать:
#!/usr/bin/perl
use strict;
use warnings;
my $job_file = readlink("/proc/self/fd/0");
if (index($job_file, " ") > 0) {
$job_file = substr($job_file, 0, index($job_file, " ") - 1);
}
my $tmp = substr($job_file, rindex($job_file, "/") + 1);
$tmp =~ s/^a([0-9a-f]{5})[0-9a-f]+/$1/;
my $job_id = hex($tmp);
if ($job_id > 0) {
printf("My AT job id is %d.\n", $job_id);
}
# end of file.