--> 情况是这样的,我管理着一个集群,有时需要更新这集群上的项目,每次手动写循环很烦人,不停的搞键盘,很累人,下面这个脚本可以让我偷偷懒,同时也减少了出错的机率,其实我使用这个脚本一段时间了,前一段时间我的工作站出了问题,一不要心将分区表删了,丢了一些资料,包括运行这个脚本的环境。花了两个小时重新写了这个脚本,赶快贴出来,下次系统崩溃后还能用得上,呵呵!
我将脚本命令为upfile.pl,放在/root/syncproject/目录下,同时这个目录下放着多个项目文件夹及一个log文件夹,远端主机上的/home/project/下存放有项目文件,我要保持本地/root/syncproject/目录下的项目是新的,然后运行脚本:
[root@supersun.biz syncproject]#./upfile.pl -h host1,host2 -p project1
这样就可以更新host1和host2上的project1项目了,rsync生成的日志保存到log文件夹下。
脚本很简单,但对于我来说挺实用。平时就应该简化自己的工作。
#!/usr/bin/perl
use strict;
use Getopt::Std;
#定义默认变量
use vars qw/
$LOCAL_PATH
$REMOTE_PATH
$LOG_PATH
@HOST_LIST
@PROJECTS
$PROJECT_NAME
/;
#本地的项目存储路径
#远端的项目存储路径
#日志存诸路径
#默认的主机列表
#可使用的项目名称
$LOCAL_PATH="/root/syncproject/";
$REMOTE_PATH="/home/project/";
$LOG_PATH="/root/syncproject/";
@HOST_LIST=qw/host1 host2 host3/;
@PROJECTS=qw/project1 project2/;
#定义命令行选项
#h 主机列表hosts
#p 项目名project
my %opts;
getopt("hp",\%opts);
#处理命令行传入的主机列表
@HOST_LIST=split /,/,$opts{h} if defined $opts{h};
#检查命令行传入的项目名是否可用
if(defined $opts{p}) {
$PROJECT_NAME=$opts{p};
my %TEST_PROJECTS;
@TEST_PROJECTS{@PROJECTS}=@PROJECTS;
unless(exists $TEST_PROJECTS{$PROJECT_NAME}){
print "错误的项目名:$PROJECT_NAME\n可用的项目名:@PROJECTS\n";
useage();
}
}else{
print "项目名未定义\n";
useage();
}
#生成命令行,并fork多进程进行更新
foreach my $HOST(@HOST_LIST){
my $COMMAND="rsync -av --delete ".$LOCAL_PATH.$PROJECT_NAME."/ ".$HOST.":"
.$REMOTE_PATH.$PROJECT_NAME."/";
if(fork){
print "更新$HOST上的$PROJECT_NAME\n";
print "Command:$COMMAND\n";
}else{
my $output=`$COMMAND`;
if($? eq 0){
print "$HOST更新成功\n";
my $file=$LOG_PATH."log/".$HOST;
open FD,'>',$file;
print FD join "\n",map $_="$HOST:$_",split /\n/,$output;
print FD "\n";
close FD;
}else{
print "$HOST更新失败\n";
print join "\n",map $_="$HOST:$_",split /\n/,$output;
print "\n";
}
exit;
}
}
#等待子进程
1 while wait_a_kid;
#等待子进程的例程
sub wait_a_kid {
my $pid=wait;
return 0 if $pid<0;
1
}
#使用说明
sub useage {
die "$0 [-h host1,host2,host3...] -p PROJECT_NAME\n";
}

发表评论