大家好,又见面了,我是你们的朋友全栈君。
集群分发脚本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!
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/137526.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...