2014-01-29 2 views
3

때 내에서 작업 '에'의 ID를 찾기는 아이디, 즉 할당 '에서'2014년 1월 28일 17시 반그것이 내가 가진 작업을 예약

에서

작업 (44) 그 일이 끝나면 나는 그 안에서 이드를 만나고 싶다. 이것은 Centos, FWIW에 있습니다. 환경 변수에 ID가 포함되지 않았 음을 확인했습니다. 해당 작업의 Perl 코드가 실행될 때 작업 ID (이 예에서는 44)를 인쇄 할 수 있기를 바랍니다.

예, atq가 실행중인 작업 옆에 = 표시되어 있지만 한 번에 두 개 이상있을 수 있음을 알고 있습니다.

작업을 예약 할 때 작업에 대한 고유 한 인수를 전달하고 ID를 캡처하고 그 인수를 어딘가에 파일에 저장하고 작업에서 읽는 것과 같이 할 수 있습니다. 그것은 내가해야 할 일이 없다면 오히려 가지 않을 많은 일입니다. 그리고 이것은 단순해야만하는 것처럼 보이지만 저는 비어 있습니다.

답변

2

다음은 ~ 3.14의 소스를 읽음으로써 계산됩니다. puts 작업 ID와 파일 이름으로 실행되는 시간은 모든 버전에서 비슷해야하지만이 내용은 확인하지 않았습니다.

시작하려면 whith at는 작업 ID와 특정 작업이 작업을 설명하는 파일 이름으로 실행되어야하는 시간을 인코딩합니다. 파일 이름의 형식은 aJJJJJTTTTTTTT입니다. 여기에서 JJJJJ은 5 자의 16 진수 문자열이며 작업 ID이며 TTTTTTTT은 작업을 실행해야하는 시간 인 8 자의 16 진수 문자열입니다. 시간은 신기원으로부터 초 단위로 저장됩니다.

작업 입력은 작업 입력 파일을 표준 입력으로 sh -c에 입력하여 실행됩니다. 운좋게도 리눅스 커널은 심볼릭 링크 인 /proc/self/fd/0을 제공한다. 이것은 현재 실행중인 프로세스의 표준 입력을 가리킨다. (실제로는 그렇게 확신 할 필요가있는 경우에 대비하여 ls -l /proc/self/fd/0로 재생한다.)

작업을 설명하는 파일이 작업이 실행될 때까지 삭제되었습니다. 그러나이 파일은 작업의 표준 입력으로 사용되기 전에 dup(2)과 중복되므로 커널에서 계속 사용할 수 있습니다. 따라서 실제로는 더 이상 보이지 않는 파일 이름에 대한 심볼릭 링크를 해결하고 있습니다. 결국 perl 스크립트에서 readlink이 대신 /foo/bar/baz 대신에 반환 될 것이므로 이것을 고려해야합니다. 그리고 우리는 우리가 필요로하는 모든 정보를 가지고있는 파일 이름에만 관심이 있습니다.

심볼릭 링크가 삭제 된 파일을 가리키는 이유는 데몬이 작업을 실행하기 전에 원본 링크를 해제하기 때문입니다. 연결 해제는 사본을 만든 후에 만 ​​수행되며 하드 링크는 a 대신 =으로 시작합니다. 이것으로 at 데몬은 실행중인 작업의 복사본이 하나만 있는지 확인하려고 시도합니다. 데몬은 execle(2)이 아닙니다. link(2)이 실패하면 구제가 될 것입니다. 원래의 파일은 open(2)dup(2) 이었기 때문에, 여전히 하드 링크를 가리키고 있기 때문에 커널은 여전히 ​​inode가 사용됩니다. 상당히 길고 가능성이 혼란을 도입 한 후

, 여기에 모두 함께 넣어하는 방법입니다 :

#!/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. 
+0

와우. 정말 인상적입니다. – user3246940