运行 来自任何地方的 Perl 代码(包括文件路径)
Run Perl Code (which includes file paths) from anywhere
我正在使用 perl 创建一个守护程序,但我无法从任何地方(根据需要)将脚本发送到 运行。该脚本将进程 ID 写入文件并记录输出。有效的代码如下,如果我尝试更改它,例如获取 pwd
并在我的文件夹名称之前插入它,我得到的错误是没有文件或目录,例如我说 $dir = pwd
然后将我的 pid 文件设置为 $dir/pid/conductor_daemon_test.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";
}
您在尝试使用 pwd
时似乎没有创建 'pid' 子目录。在尝试创建 pid 文件之前创建它。
另外:请使用词法文件句柄和 open 的 3 参数形式:open (my $fh, '>', $filename)
而不是 GLOB (FILE
) 和 '>filename.pid'
使用 FindBin 这是一个核心模块,您可以轻松找到脚本的位置:
DESCRIPTION
Locates the full path to the script bin directory to allow the use of
paths relative to the bin directory.
我的建议是您可以为脚本创建一个模式,这样您就可以将所有内容放在同一个文件夹中,例如:
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";
您可以导出以下变量:
EXPORTABLE VARIABLES
$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
然后我想你不会再有任何位置问题了。
我正在使用 perl 创建一个守护程序,但我无法从任何地方(根据需要)将脚本发送到 运行。该脚本将进程 ID 写入文件并记录输出。有效的代码如下,如果我尝试更改它,例如获取 pwd
并在我的文件夹名称之前插入它,我得到的错误是没有文件或目录,例如我说 $dir = pwd
然后将我的 pid 文件设置为 $dir/pid/conductor_daemon_test.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";
}
您在尝试使用 pwd
时似乎没有创建 'pid' 子目录。在尝试创建 pid 文件之前创建它。
另外:请使用词法文件句柄和 open 的 3 参数形式:open (my $fh, '>', $filename)
而不是 GLOB (FILE
) 和 '>filename.pid'
使用 FindBin 这是一个核心模块,您可以轻松找到脚本的位置:
DESCRIPTION
Locates the full path to the script bin directory to allow the use of paths relative to the bin directory.
我的建议是您可以为脚本创建一个模式,这样您就可以将所有内容放在同一个文件夹中,例如:
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";
您可以导出以下变量:
EXPORTABLE VARIABLES
$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
然后我想你不会再有任何位置问题了。