2017-01-27 10 views
0

나는 perl을 사용하여 데몬을 만들고 있는데, 원하는 곳에서 스크립트를 실행하는 데 문제가 있습니다. 스크립트는 프로세스 ID를 파일에 기록하고 출력도 로깅합니다. 작동하는 코드는 아래와 같습니다. 예를 들어, pwd을 입력하고 폴더 이름 앞에이 파일을 삽입하면 오류가 발생합니다. 예를 들어 파일이나 디렉토리가 없습니다. 나는 $ dir = pwd을 말하고 $ pir/conductor_daemon_test.pid와 같이 내 pid 파일을 설정한다. 어떤 아이디어라도 위치에 관계없이이 작업을 수행하는 방법은 무엇입니까?어디서나 펄 코드 (파일 경로 포함)를 실행하십시오.

#!/usr/bin/perl 

use POSIX qw(setsid); 
my $proc; 
my $error; 
my $file="conductor.pl"; 
my $pidfile=">./home/perl_daemon/conductor/pid/conductor_daemon_test.pid"; 
my$pid2check="/home/perl_daemon/conductor/pid/conductor_daemon_test.pid"; 
my $pid; 

#Make it a daemon 
$proc = Daemonize(); 

if(!$error){ 
    LogMessage("$file:PID $proc: Begin"); 
} 

#Write Pid Information 
if(!$error){ 
    if(-e $pid2check){ 
      LogMessage("$file : PID File $pid2check already exists. Exiting.."); 
      exit(0); 
    } 
    else { 
      unless(open(FILE, $pidfile)){ 
        $error = "Error opening file for writing ".$!; 
      } 
    } 
    } 
    if(!$error) { 
    LogMessage("$file: PID $proc: Writing pid information to $pidfile"); 
    print FILE $proc ."\n"; 
    close(FILE); 
    } 

    my $EXIT = 0; 
    $SIG{TERM} = sub{ LogMessage("Caught exit signal!\n");$EXIT=1}; 

    #Main loop of the Daemon 
    while (!$error){ 

    sleep(100); 
    LogMessage("Hello World"); 


    do { LogMessage("Graceful exit!\n"); exit } if $EXIT; 

    } 
    if($error){ 
    LogMessage("$file:PID $proc:Error $error"); 
    } 

    LogMessage ("$file: PID $proc: END");enter code here 

    exit(0); 

    # 
    #Subs 
    # 
    ##################################### 

    #  Daemonize 
    # 
    ##################################### 
    # 
    #  Used to make this program a daemon 
    #  Also to redirect STDIN, STDERR, STDOUT 
    #  Returns PID 
    # 
    ######## 

sub Daemonize { 
    #Ensure that the current directory is the working directory 
    unless(chdir '/'){ 
      $error = "Can't chdir to /:$!"; 
    } 
    #Ensure that the file mode mask is changed 
    unless(umask 0){ 
      $error="Unable to umask 0"; 
    } 
    #Ensure the STDIN is closed 
    unless(open STDIN, '/dev/null'){ 
      $error="Can't read /dev/null:$!"; 
    } 
    #All print statements will now be sent to our log file 
    unless(open STDOUT, '>> /home/perl_daemon/conductor/log/conductor_daemon_test.log'){ 
      $error="Can't read /home/perl_daemon/conductor/log/conductor_daemon_test.log:$!"; 
    } 
#All error messages will now be sent to our log file 
    unless(open STDERR, '>>/home/perl_daemon/conductor/log/conductor_daemon_test.log'){ 
      $error="Can't write to /home/perl_daemon/conductor/log/conductor_daemon_test.log:$!"; 
    } 

#Fork off the parent process 
defined($pid = fork); 
#Exit if $pid exists(parent) 
exit(0) if $pid; 

#As Child 
#Create a new SID for the child process 
setsid(); 
$proc = $$; 
return($proc); 
} 


#### 
# 
#  Log Message 
# 
#  Used to log messages 
# 
###### 

sub LogMessage { 
    my $message = $_[0]; 
    print localtime()." $message\n"; 
} 

답변

0

pwd를 사용하려고 할 때 'PID'하위 디렉토리를 작성하지 않은 것 같다. pid 파일을 생성하기 전에 생성하십시오.

또한

: 어휘 파일 핸들을 사용하십시오와 3 인자 개방의 형태 : 대신 globs와의 open (my $fh, '>', $filename) (FILE)와 '>filename.pid'

+0

감사합니다.이 파일은 어디에서나 실행되는 것을 막는 문제였습니다. – AlanDev1989

1

쉽게 스크립트의 위치를 ​​찾을 수있는 코어 모듈은 FindBin 사용 :

설명

는 bin 디렉토리를 기준으로 경로를 사용할 수 있도록 스크립트 bin 디렉토리의 전체 경로를 찾습니다.

use FindBin qw($RealBin); 

my $pidfile=">.$RealBin/pid/conductor_daemon_test.pid"; 
my $pid2check="$RealBin/pid/conductor_daemon_test.pid"; 

:

daemon/script.pl 
daemon/pid/ <- pid files 
daemon/log/ <- logs 

그래서 코드는 다음과 같이 될 것이다 :

나의 제안은 당신이 좋아하는 같은 폴더에 모든 것을 넣을 수 있도록 스크립트에 대한 패턴을 만들 수있다 아래 변수를 내보낼 수 있습니다.

수출 가능한 문자

$Bin   - path to bin directory from where script was invoked 
$Script  - basename of script from which perl was invoked 
$RealBin  - $Bin with all links resolved 
$RealScript - $Script with all links resolved 

그리고는 당신이 더 이상 위치에 문제가없는 것 같아요.