2017-01-27 3 views
0

私はperlを使ってデーモンを作成していますが、どこからでもスクリプトを実行することができません。スクリプトはプロセスIDをファイルに書き込み、出力もログに記録します。私がこれを変えようとすると、例えばpwdを得て、これを挿入する前に、私が得たエラーは、ファイルやディレクトリがないということです。私は$ dir = pwdと言って、次に$ dir/pid/conductor_daemon_test.pidに自分のpidファイルを設定します。どのようにアイデアをどのように場所に関係なく実行するには?どこからでもPerlコード(ファイルパスを含む)を実行する

#!/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引数形式を使用してください:open (my $fh, '>', $filename)の代わりに、グロブ(FILE)と'>filename.pid'

+0

ありがとうございました。これはファイルがどこからでも実行されないようにするための問題でした。 – AlanDev1989

1

は、あなたが簡単にあなたのスクリプトの場所を見つけることができますコアモジュールであるFindBinを使用します:

DESCRIPTION

はbinディレクトリからの相対 パスの使用を可能にするスクリプトbinディレクトリへの完全なパスを検索します。だからあなたのコードは次のようになります

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

use FindBin qw($RealBin); 

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

私の提案はあなたのような同じフォルダにすべてを置くことができますので、あなたのスクリプトのパターンを作成することができています以下の変数をエクスポートできます。

エクスポート可能な文字

$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 

そして私は、あなたはもう場所で何か問題を持っていないだろうと思います。

関連する問題