Zookeeper集群自动启动脚本 -- export 的注意点

前提补充:我们可以通过ssh操作另一台机器
测试:

ssh bd2 mkdir /root/bd1

上面的这条命令就可以在 bd2 上新建一个文件夹了 bd1

尝试在bd1上启动bd2的zookeeper服务:

ssh bd2 /root/apps/zookeeper-3.4.5/bin/zkServer.sh start

Zookeeper集群自动启动脚本 -- export 的注意点

但是发现 bd2 上面的 zookeeper并没有启动
原因是zookeeper启动的时候需要一些环境变量,特别是JAVA_HOME,而在bd1上使用ssh的时候其实只是一个bash的会话,在这个会话里面是没有这个JAVA_HOME的,所以启动不了

技术点: export 的知识点

a=1
echo $a

Zookeeper集群自动启动脚本 -- export 的注意点
编写 s1.sh 脚本

#!/bin/bash
echo $a

执行这个脚本:

Zookeeper集群自动启动脚本 -- export 的注意点

发现并没有打印之前定义的a
原因是:
使用pstree 查看:
Zookeeper集群自动启动脚本 -- export 的注意点
注意 bash这个进程 里面定义了一个变量a
当执行 ./s1.sh的时候会在bash进程下面开启一个新的进程,那么这个新的进程是不能获取到父进程 bash 的变量的

unset a    将设置的变量进行撤销

使用export来定义变量:

export a=1

然后执行脚本 ./s1.sh 会将这个变量a的值打印出来

再来一个测试的例子:
s1.sh:
Zookeeper集群自动启动脚本 -- export 的注意点
a 在外面使用 export进行定义了 并且在 s1.sh里面调用了上s2.sh

s2.sh:
Zookeeper集群自动启动脚本 -- export 的注意点

执行 s1.sh:
Zookeeper集群自动启动脚本 -- export 的注意点

在s2.sh里面打印的b是没有值的,如果在s1.sh对b这个变量使用export修饰的话,那么在上里面的b是可以打印出来的:

Zookeeper集群自动启动脚本 -- export 的注意点

Zookeeper集群自动启动脚本 -- export 的注意点

但是需要注意的一点:

Zookeeper集群自动启动脚本 -- export 的注意点
在外面. 变量a的值是可以获取的,但是变量b的值是无法获取的

原因是:export出来的变量只有当前进程以及当前进程的子进程里面才有,在父进程里面是没用的

那么如果让export修饰的变量在父进程里面也有用?
Zookeeper集群自动启动脚本 -- 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 的注意点
zookeeper启动起来了:

总结:

  1. export A=1 定义的变量,会对自己所在的shell进程及其子进程生效
  2. B=1 定义的变量,只对自己所在的shell进程生效
  3. 在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
为了可以在任意的地方都运行这个脚本,所以要把这个脚本所在的目录配置在环境变量里面:
Zookeeper集群自动启动脚本 -- export 的注意点
你会发现 这个 /root/bin本身就在环境变量里面,如果是其他的目录则应该在 PATH上面进行追加

配置了免密登录的话,直接 ./startzk.sh就可以启动zookeeper集群了.
Zookeeper集群自动启动脚本 -- export 的注意点