perl进程管理一例

  1 #!/usr/bin/perl -w
  2 use strict;
  3 use warnings;
  4 use DBI;
  5 
  6 ####
  7 #   这里进行服务器任务管理
  8 ##
  9 #字符串映射函数
 10 our %actions = (
 11     "check" => \&pcheck,
 12     "run" => \&prun,
 13     "run_nohup" => \&run_nohup,
 14     "kill" => \&pkill
 15 );
 16 our $home = "/var/www/html";
 17 our $public_home = "/var/www/html/public" ;
 18 our $log_home = "/var/www/html/yfcloud_admin/Public/log" ;
 19 
 20 our $host = "XXX" ; 
 21 our $database = "XXX" ;
 22 our $db_user = "XXX";
 23 our $db_pass = "XXX";
 24 
 25 #程序路径
 26 our $ppath = "" ; 
 27 #程序名
 28 our $pname = "" ;
 29 #日志文件
 30 our $log_file = "log" ; 
 31 
 32 #检测进程状态,返回PID
 33 # 如果同进程不在运行,则返回空
 34 sub pcheck
 35 {
 36     # grep 排除perl本身的进程
 37     my $cmd = "ps -ef | grep " . $pname . " | grep -v grep | grep -v perl | awk '{print \$2}'";
 38     my $ret = `$cmd` ;
 39     chomp $ret;
 40     #如果有多个进程PID,则返回第一个pid
 41     if( $ret =~ /\n/ ){
 42         $ret = ( split /\n/, $ret )[0] ; 
 43     }
 44     ($ret eq "") ? print 0 : print $ret ;
 45 }
 46 
 47 #结束进程,返回成功与否
 48 # 0 表示成功
 49 sub pkill
 50 {
 51     my $cmd = "killall $pname";
 52     my $ret = `$cmd`;
 53     print $? ; 
 54 }
 55 
 56 # 参数需要是 程序的全路径 
 57 # 启动进程并后台运行,并返回PID
 58 # 启动进程后,需要将进程的PID及日志文件写入数据库
 59 # shell输出格式如下: [1] 15758
 60 sub prun
 61 {
 62     my $cmd = "$pname";
 63     run_exec($cmd);
 64 }
 65 
 66 # 后台以nuhup方式运行
 67 sub run_nohup
 68 {
 69     my $cmd = "nohup $pname" ;
 70     run_exec($cmd);
 71 }
 72 
 73 # 命令格式如下: perl ProcessManager.pl $pname $action 
 74 sub main
 75 {
 76     umask(0);
 77     #print "begin\n";
 78     #这里接收参数并执行相应的操作
 79     if( @ARGV < 2 )
 80     {
 81         print "arguments error!\nusage:perl ProcessManager.pl command action\n";
 82         exit 1;
 83     }
 84     $pname = $ARGV[0] ;  #这里使用全局变量算了 ~_~
 85     my $action = $ARGV[1] ;
 86     #判断操作是否合法
 87     if( $actions{$action} ){
 88         $actions{$action}->() ;
 89     }else{
 90         print "undeclare action!check you action!\n";
 91         exit 1;
 92     }
 93 }
 94 
 95 main();
 96 
 97 
 98 
 99 ############
100 ##这里是一些工具函数
101 ############
102 sub gettime
103 {
104    my($sec,$min,$hour,$day,$mon,$year) = (localtime(time));
105    $mon +=1 ;
106    $day = ($day < 10 )?"0$day":$day;
107    $mon = ($mon < 10 )?"0$mon":$mon;
108    $min = ($min < 10 )?"0$min":$min;
109 
110    return "$mon$day$hour$min" ; 
111 }
112 
113 sub run_exec
114 {
115     my $cmd = shift ;
116     #先检测文件是否存在,可执行
117     if( -x $pname ){
118         $pname =~ m#.+/(.+)# ; #获得程序名(包括后缀名)作为日志文件名称
119         # 建立程序的日志文件目录
120         my $name = $1 ;
121         mkdir "$log_home/$name" or die("cannot create dir:$name") unless ( -e "$log_home/$name" );
122         $log_file = "$log_home/$name/".gettime() ;
123         # print "log_file : $log_file\n";
124         $cmd .= " > $log_file 2>&1 &";
125         addToDB($name,$log_file);
126         my $pid = fork;
127         if (not $pid) {
128             $pid = $$; 
129             print $pid ; 
130             exec($cmd); #exec是异步的,执行完后就脱离perl程序了
131         }
132     }else{
133         print "$pname cannot be excuted\n";
134         exit 1;
135     }
136 }
137 
138 # 将日志写入日志
139 sub addToDB
140 {
141     my ($progName,$log_file) = @_ ;
142     my $createtime = time ;
143     my $db_handle = DBI->connect("DBI:mysql:database=$database;host=$host", $db_user, $db_pass, {'RaiseError' => 1})|| die "Could not connect to database: $DBI::errstr";
144     
145     my $sql = "insert into log (name,log_file,createtime) values (?,?,?)"; 
146     my $sth = $db_handle->prepare($sql);
147     
148     $sth->execute($progName, $log_file , $createtime) or die $DBI::errstr;
149     $sth->finish();
150     
151     $db_handle->disconnect();
152 }

 

posted @ 2013-07-13 14:09  ifeixiang  阅读(2275)  评论(0编辑  收藏  举报