xsync集群分发脚本的改良[通俗易懂]

xsync集群分发脚本的改良[通俗易懂]集群分发脚本xsync带多参数1.0增强了一下带参个数xsync1.0#!/bin/bash#校验参数pcount=$#if(($pcount==0))then exitfi#获取用户名user=`whoami`#获取文件名,路径for((i=1;i<=$#;i++))#对多个传参进行分析dob=${!i} #这里用到了“间接变量”语法fname=`basename$b`dname=`dirname$b`dir=`cd$dname;pwd`

大家好,又见面了,我是你们的朋友全栈君。

集群分发脚本xsync带多参数1.0到2.0

不好用的分发脚本,缺点:不能同时传多个文件,集群规模需要手动调整,某些变量不是完全解耦

#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if((pcount==0)); then
echo no args;
exit;
fi

#2 获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname

#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir

#4 获取当前用户名称
user=`whoami`

#5 循环
for((host=103; host<105; host++)); do
        echo ------------------- hadoop$host --------------
        rsync -av $pdir/$fname $user@hadoop$host:$pdir
done

xsync1.0

增强了一下带参个数

起因 拟了一个test脚本尝试实现 循环遍历后面跟的多个文件的basename,获取文件名称

#!/bin/bash
#循环遍历,获取文件名称
#for((i=1;i<=$#;i++))
for i in `seq $#`
do
   echo `basename $i`
done

测试结果:

[root@flinkbeginning ~]# ./test 3.txt 5.txt 
1
2

无法获取正确的文件名称 3.txt 5.txt;
我需要把 $i 作为一个整体,继续对其进行 $ 取值,但是 $$i 在shell脚本中直接用是不成立的

#!/bin/bash
#for((i=1;i<=$#;i++))
for i in `seq $#`
do
    echo $$i
    #echo `basename $i`
done

测试结果

[root@flinkbeginning ~]# ./test.sh 3.txt 5.txt 
125435i
125435i

此处↓

知识点:间接变量

#!/bin/bash
#2 获取文件名,路径
#for((i=1;i<=$#;i++))
for i in `seq $#`   #对多个传参进行分析 例如:~/xsync /opt/module /etc/profile
do
file=${ 
   !i}		#这里用到了 “间接变量”语法 或者 eval file=\$$i
#eval file=\$$i
fname=`basename $file`
dname=`dirname $file`
dir=`cd $dname;pwd`
#echo $dir
done

解释一下,用到一个知识点:间接变量

1.使用间接变量你这个使用间接变量就可以解决了,这是我之前的笔记:
什么是间接变量:假设一个变量的值是第二个变量的名字,举个例子:x=a, a=123, 就是通过x这个变量,来引用123这个值,bash4.0-中文文档里的介绍:在很多其它语言中,可以用

$$A

来表示以 $A 为名称的间接变量,而 bash shell中不可以,即使

$$A

这样的也不可以;bash shell只识别感叹号形式的间接变量。不过,这个功能在其它的shell 中可能没有。所以,为了增强可移植性,可以这样写:

eval echo \$$B
或者
echo b=${!b}

下面是三个简单的例子:

#!/bin/bash
b=a
a=1
echo b="$$b"

执行结果为: b=1385b

#!/bin/bash
b=a
a=1
echo b=${ 
   !b}

执行结果为:b=1

#!/bin/bash
a=1
b=a
eval echo b=\$$b

执行结果为:b=1

前一种方法不行,后面两种方法都可以!注:eval的作用是再次执行命令行处理,也就是说,对一个命令行,执行两次命令行处理(记住是执行两次命令行处理,不是执行两次命令)。
我刚在centos7上的测试结果:
源码:

#!/bin/bash
for i in `seq $#`
do
    eval b=\$$i
    echo 'b='$b

    c=${ 
   !i}
    echo 'c='$c
done 

执行结果:

# sh test.sh 123

b=123
c=123

2.使用数组
楼上有提到使用数组了,使用数组确实简单一点 ,这是例子:

# cat test.sh

#!/bin/bash

#把参数转化为数组
a=( "$@" )     

#遍历数组
for i in ${a[*]};do
    echo $i
done 

执行结果:

# sh test.sh 123 456

123
456

希望对你能有所帮助。

xsync 2.0

#!/bin/bash
#校验参数
pcount=$#
if (($pcount==0))
then
	exit
fi

#获取用户名
user=`whoami`

#获取文件名,路径 例如: 
#for((i=1;i<=$#;i++))
for i in `seq $#`
do
	file=${ 
   !i}
	fname=`basename $file`
	dname=`dirname $file`
	dir=`cd $dname;pwd`

#循环发
    #需要优先配置/etc/hosts下的hostname列对应集群信息
    #或者awk配合正则使用,我这里只是学习环境所以我只需要匹配我的主机名含有flink就可以了
    #192.168.66.110 flinkbeginning
    #192.168.66.111 flinkslave1
    #192.168.66.112 flinkslave2
    #140.82.113.4 github
    #140.82.114.4 github
    
	# for host in `awk -F " " '{if(NR>2){print $2}}' /etc/hosts`
	#这里使用 正则
	for host in `awk '/flink/{print $2}' /etc/hosts`
	do
		echo -------------$fname-TO-$host--------------
        rsync -ral $dname/$fname $user@$host:$dir
		if (($?==0))
		then
			echo "传输成功!"
		else
			echo "传输失败!"
		fi
	done
done

用到了awk工具,NR是awk内置参数 代表 “行号”

[root@flinkbeginning ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.66.110 flinkbeginning
192.168.66.111 flinkslave1
192.168.66.112 flinkslave2
140.82.113.4 github
140.82.114.4 github

[root@flinkbeginning ~]# awk -F " " '{if(NR>2){print $2}}' /etc/hosts
flinkbeginning
flinkslave1
flinkslave2
github
github

此处awk的if是不严谨的,按需要应该采用awk配合正则。

awk '/flink/{print $2}' /etc/hosts
此处的"flink"可以灵活替换
“$”理论基础 —— { 
   print $0}是可以输出整行的信息

然后我把 xsync的脚本文件、module 承载软件的文件夹 和 /etc/profile 环境文件 同时分发尝试:

[root@flinkbeginning ~]# xsync ~/xsync /opt/module /etc/profile
-------------xsync-TO-flinkbeginning--------------
传输成功!
-------------xsync-TO-flinkslave1--------------
传输成功!
-------------xsync-TO-flinkslave2--------------
传输成功!
-------------module-TO-flinkbeginning--------------
传输成功!
-------------module-TO-flinkslave1--------------
传输成功!
-------------module-TO-flinkslave2--------------
传输成功!
-------------profile-TO-flinkbeginning--------------
传输成功!
-------------profile-TO-flinkslave1--------------
传输成功!
-------------profile-TO-flinkslave2--------------
传输成功!

去从机器上创建软连接
[root@flinkslave1 ~]# ln -s ~/xsync /usr/bin/xsync
[root@flinkslave2 ~]# ln -s ~/xsync /usr/bin/xsync
或者直接在主机器上写个脚本
对于脚本的方式:
  有些远程执行的命令内容较多,单一命令无法完成,考虑脚本方式实现:

#!/bin/bash
#获取用户名
user=`whoami`

for host in `awk '/flink/{print $2}' /etc/hosts`
do
    ssh $user@$host > /dev/null 2>&1 << eeooff ln -s ~/xsync /usr/bin/xsync exit eeooff
echo "$host xsync is ok!"
done

远程执行的内容在“<< eeooff ” 至“ eeooff ”之间,在远程机器上的操作就位于其中,注意的点:

<< eeooff,ssh后直到遇到eeooff这样的内容结束,eeooff可以随便修改成其他形式。
重定向目的在于不显示远程的输出了
在结束前,加exit退出远程节点

[root@flinkbeginning ~]# ./ssh-xsync 
flinkslave1 xsync is ok!
flinkslave2 xsync is ok!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137526.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c#操作xml文件

    c#操作xml文件

    2021年9月4日
    79
  • qt的内存映射

    qt的内存映射uchar*QFileDevice::map(qint64offset,qint64size,QFileDevice::MemoryMapFlagsflags=NoOptions)从偏移量开始将文件的大小字节映射到内存中。应该打开一个文件以使映射成功,但在映射内存之后,该文件不需要保持打开状态。当QFile被销毁或用这个对象打开一个新文件时,任何未被映射的映射都将被自动取消映射。映射将具有与文件相同的打开模式(读和/或写),除非使用maprivateOption,在这种情况下,始终可以

    2022年6月15日
    107
  • 使用 Chrome Timeline 来优化页面性能

    使用 Chrome Timeline 来优化页面性能

    2021年9月17日
    45
  • 通用 PE 工具箱1.9.6(XP内核)by Uepon(李培聪)[通俗易懂]

    通用 PE 工具箱1.9.6(XP内核)by Uepon(李培聪)[通俗易懂]通用PE工具箱1.9.6(XP内核)byUepon(李培聪)官网:http://hi.baidu.com/uepon?page=21.8版论坛帖子:http://bbs.wuyou.net/forum.php?mod=viewthread&amp;tid=119749通用PE1.9.6介绍:http://hi.baidu.com/uepon/item/ceafeb322ba148b9633a…

    2022年7月14日
    22
  • java.sql.SQLException: ORA-01008: 并非所有变量都已绑定的解决方法「建议收藏」

    java.sql.SQLException: ORA-01008: 并非所有变量都已绑定的解决方法「建议收藏」错误:在使用PreparedStatement的时候,可以很好地避免像Statement的sql注入问题,但是在这里使用PreparedStatement对象和使用Statement对象来执行sql语句有一定的区别。PreparedStatement的对象通过:PreparedStatementp=con.preparedStatement(str);来执行sql语句,其中str是s…

    2022年9月4日
    3
  • log4cpp 使用完全手册「建议收藏」

    log4cpp 使用完全手册「建议收藏」原文链接 点击打开链接一、log4cpp概述     Log4cpp是一个开源的C++类库,它提供了C++程序中使用日志和跟踪调试的功能,它的优点如下:提供应用程序运行上下文,方便跟踪调试;可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等;可以动态控制日志记录级别,在效率和功能中进行调整;所有配置可以通过配置文件进行动态调整;多语言支持,包括Ja…

    2022年7月13日
    20

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号