前提补充:我们可以通过ssh操作另一台机器
测试:
ssh bd2 mkdir /root/bd1
上面的这条命令就可以在 bd2 上新建一个文件夹了 bd1
尝试在bd1上启动bd2的zookeeper服务:
ssh bd2 /root/apps/zookeeper-3.4.5/bin/zkServer.sh start
但是发现 bd2 上面的 zookeeper并没有启动
原因是zookeeper启动的时候需要一些环境变量,特别是JAVA_HOME,而在bd1上使用ssh的时候其实只是一个bash的会话,在这个会话里面是没有这个JAVA_HOME的,所以启动不了
技术点: export 的知识点
a=1
echo $a
编写 s1.sh 脚本
#!/bin/bash
echo $a
执行这个脚本:
发现并没有打印之前定义的a
原因是:
使用pstree 查看:
注意 bash这个进程 里面定义了一个变量a
当执行 ./s1.sh的时候会在bash进程下面开启一个新的进程,那么这个新的进程是不能获取到父进程 bash 的变量的
unset a 将设置的变量进行撤销
使用export来定义变量:
export a=1
然后执行脚本 ./s1.sh 会将这个变量a的值打印出来
再来一个测试的例子:
s1.sh:
a 在外面使用 export进行定义了 并且在 s1.sh里面调用了上s2.sh
执行 s1.sh:
在s2.sh里面打印的b是没有值的,如果在s1.sh对b这个变量使用export修饰的话,那么在上里面的b是可以打印出来的:
但是需要注意的一点:
在外面. 变量a的值是可以获取的,但是变量b的值是无法获取的
原因是:export出来的变量只有当前进程以及当前进程的子进程里面才有,在父进程里面是没用的
那么如果让export修饰的变量在父进程里面也有用?
source 会把定义在脚本文件里面的变量,放到当前这个shell里面,而export会把变量放在它的进程里面以及子进程里面.
所以回到原问题:
ssh bd2 /root/apps/zookeeper-3.4.5/bin/zkServer.sh start
这种情况是没有JAVA_HOME的
因为使用ssh进行操作会跟bd2的进程处以同一个进程中
所以应该使用source
ssh bd2 "source /etc/profile;/root/apps/zookeeper-3.4.5/bin/zkServer.sh start"
zookeeper启动起来了:
总结:
- export A=1 定义的变量,会对自己所在的shell进程及其子进程生效
- B=1 定义的变量,只对自己所在的shell进程生效
- 在script.sh定义的变量,在当前登录的shell进程中, source script.sh时,脚本中定义的变量也会进入当前登录的进程
启动zookeeper集群的脚本:
#!/bin/bash
echo "Starting zkServer ..."
for i in 1 2 3
do
ssh bd$i "source /etc/profile;/root/apps/zookeeper-3.4.5/bin/zkServer.sh start"
done
chmod +x startzk.sh
startzk.sh这个脚本所在的目录是:
/root/bin
为了可以在任意的地方都运行这个脚本,所以要把这个脚本所在的目录配置在环境变量里面:
你会发现 这个 /root/bin本身就在环境变量里面,如果是其他的目录则应该在 PATH上面进行追加
配置了免密登录的话,直接 ./startzk.sh就可以启动zookeeper集群了.