Zookeeper使用ssh远程启动脚本失败的解决方案

7 篇文章 0 订阅
4 篇文章 0 订阅

前言

  • 本文主要记录一次解决问题的经历

问题描述

  • 在编写zookeeper群起脚本时,想要基于ssh命令来启动集群中所有zookeeper服务器节点。但是在使用ssh远程执行远端脚本时,控制台输出显示远端脚本已经正常运行结束,远端zookeeper进程实际上却未能运行。使用的ssh命令如下:
[tomandersen@hadoop101 bin]$ ssh hadoop102 "$ZOOKEEPER_HOME/bin/zkServer.sh start"
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.14/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

解决过程

1)查看远端主机的运行日志zookeeper.out:

  • zookeeper.out默认输出在启动zkServer.sh脚本的当前路径下,查看其中内容,如下所示:
[tomandersen@hadoop102 runtime]$ cat zookeeper.out 
nohup: 无法运行命令"java": 没有那个文件或目录
  • 发现脚本中无法找到java命令(猜测可能是环境变量的问题)

2)尝试在脚本zkServer.sh中定位java命令使用位置:

[tomandersen@hadoop102 bin]$ cat zkServer.sh | grep java -n
20:# it should be linked to and not copied. Things like java jar files are found
39:# http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
  • 但发现其中都是注释,并没有显示调用java命令。然后查看zkServer.sh中的内容,发现此脚本在开头还使用. zkEnv.sh的方式运行了zkEnv.sh脚本,因此我们再去此脚本中定位java命令

3)尝试在脚本zkEnv.sh中定位java命令使用位置:

[tomandersen@hadoop102 bin]$ cat zkEnv.sh | grep java -n
49:if [ -f "$ZOOCFGDIR/java.env" ]
51:    . "$ZOOCFGDIR/java.env"
69:  JAVA="$JAVA_HOME/bin/java"
71:  JAVA=java
  • 查看具体程序段:
68 if [ "$JAVA_HOME" != "" ]; then
69   JAVA="$JAVA_HOME/bin/java"
70 else
71   JAVA=java
72 fi
  • 结果发现此段程序并没有什么异常,于是尝试验证之前的推测,可能是环境变量导致此次错误

4)查看远端环境变量主机设置:

  • 使用ssh登录远端主机后,查看Java环境变量:
[tomandersen@hadoop102 bin]$ echo $JAVA_HOME
/opt/module/jdk1.8.0_221
[tomandersen@hadoop102 bin]$ which java
/opt/module/jdk1.8.0_221/bin/java
[tomandersen@hadoop102 bin]$ echo $PATH | grep $JAVA_HOME
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8.0_221/bin:/opt/module/hadoop-2.7.7/bin:/opt/module/hadoop-2.7.7/sbin:/opt/module/zookeeper-3.4.14/bin:/home/TomAndersen/.local/bin:/home/TomAndersen/bin
  • 结果发现环境变量配置正常,然后尝试使用ssh命令远程调用Java环境变量,查看是否能正常输出:
[tomandersen@hadoop101 bin]$ ssh hadoop102 "echo \$JAVA_HOME"

[tomandersen@hadoop101 bin]$ ssh hadoop102 "which java"
which: no java in (/usr/local/bin:/usr/bin)
[tomandersen@hadoop101 bin]$ ssh hadoop102 "echo \$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
  • 注意:在远端执行命令读取远端变量时,需要将美元符号转义即\$
  • 显然使用ssh远程直接执行Shell命令既不能读取之前设置的环境变量(如JAVA_HOME和PATH),也无法使用java命令,但是远端主机各个环境变量设置正常
  • 于是猜测是不是使用ssh工具执行远端脚本时,没有加载环境变量。

5)验证猜想

  • 接下来在远端主机上创建测试脚本test.sh,用于测试是否使用ssh工具远端执行此脚本时无法读取环境变量,其中测试脚本内容如下:
1 echo $PATH
2 echo $JAVA_HOME
3 which java
  • 使用ssh远程执行此脚本:
[tomandersen@hadoop101 ~]$ ssh hadoop102 "~/test.sh"
/usr/local/bin:/usr/bin

which: no java in (/usr/local/bin:/usr/bin)
  • 至此我们可以得出结果,使用ssh执行远端脚本时,在脚本内是没有加载环境变量的,即没有加载/etc/profile文件,因此我们修改原始ssh远程执行命令,在前面加上source /etc/profile,即主动加载系统环境变量,然后发现脚本能够正常调用环境变量:
[tomandersen@hadoop101 ~]$ ssh hadoop102 "source /etc/profile;~/test.sh"
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8.0_221/bin:/opt/module/hadoop-2.7.7/bin:/opt/module/hadoop-2.7.7/sbin:/opt/module/zookeeper-3.4.14/bin
/opt/module/jdk1.8.0_221
/opt/module/jdk1.8.0_221/bin/java
  • 至此问题解决

解决方案

① 在ssh远程执行的正式命令之前加上source /etc/profile;,即主动加载环境变量

② 同理在远程主机对应用户的~/.bashrc文件末尾加入source /etc/profile,也是同样的效果(但不建议)

③ 在使用ssh时,使用重定向输入的方式执行命令,会自动加载环境变量,参考


参考资料

ssh连接远程主机执行脚本的环境变量问题


End~

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值