1.引子

前几天有一个需求是这样的:本机的shell脚本,通过远程调用另一台机子上的shell脚本,来完成对远程机子上分发的Java程序的执行和其他操作。看上去挺容易,实际上也不难。

第一步:用scp从本机向目的机子分发Java程序;

第二步:编写shell脚本,用ssh完成调用。

然而,问题来了。

2.分析

先声明:第一,Local和Remote两个机子上的JDK安装路径、环境变量(都配置在.bash_profile中)、使用的版本统统一样;第二,Java程序在Remote机上用shell脚本是可以启起来的。
首先,给出一个用于测试的简单Java代码:
public class Hello{
public static void main(String[] args){
System.out.println("Test Successful, Hello!");
}
}

然后,是Local shell脚本:

#!/usr/bin/env bash

echo "Local Java Version:"
echo `java -version`
echo "Remote Java Version:"
ssh blade27 "java -version"
echo "==========================================================="
ssh blade27 "rpm -qa | grep java"
echo "==========================================================="
ssh blade27 ". /home/wangpeng/zhiming/test/test.sh arguments"
echo "invoke done!"

最后,是Remote shell脚本:

#!/usr/bin/env bash

echo "Remote Java Home:"
echo $JAVA_HOME
echo "===============Execute Java Program============="
java -cp /home/wangpeng/zhiming/test/Hello.jar Hello
echo "================================================"
echo "Success, make it!"
echo "This is a args: $1"


我们先直接运行看看结果:

我们可以明显的发现以下问题:1.Local Java Version和Remote Java Version不一样;2.Remote shell根本就没有找到已经配置好的环境变量$JAVA_HOME;3.Remote启用了Linux自带的OpenJDK。因此,才会报错:Java程序的编译和运行时的Java Version不一样。
那么,现在我们就来分析原因。由运行结果可以看出,Remote机上配置环境变量的.bash_profile文件,在ssh连接时根本没有被加载,而ssh连接别的机子,启用的shell是non-login + non-interactive模式,即非登录非交互模式,从而导致.bash_profile文件没有被加载。
注:关于ssh连接远程主机执行脚本及配置文件加载顺序的介绍参考http://feihu.me/blog/2014/env-problem-when-ssh-executing-command-on-remote/#userconsent#这个链接的文件(必须注意:Linux不同版本其文件加载顺序不同,不可照搬)。
因此,我就不多介绍配置文件加载和ssh连接模式了。

3.解决方案

由于那篇文件介绍的解决方案可能会因Linux版本的不同而发现一些变化,我这里就介绍比较简单却啰嗦的方法。

方式一:在Remote机上的shell脚本的开头重新配置Java的环境变量
JAVA_HOME=/home/wangpeng/install/jdk1.7.0_25
export PATH=$JAVA_HOME/bin:$PATH

方式二:同样还是在Remote shell的开头设置,用source使.basn_profile文件生效

source /home/wangpeng/.bash_profile
方式三:干掉OpenJdk(注:一般我们使用的用户没有权限)

然后我们再来调用一次,观察运行结果:


虽然在ssh连接Remote的时候,Remote仍然启用的是OpenJdk,但是由于我们在Remote shell里重新是环境变量生效了,所以在执行Remote shell时,用的是自己安装的JDK。
参考文献
Linux man

版权声明:本文为博主原创文章,未经博主允许不得转载。

最新文章

  1. Android中用TextView显示大量文字的方法
  2. pair的使用
  3. python使用uuid库生成唯一id
  4. C++ 在Windows下截取整个屏幕 和 指定句柄窗口的屏幕
  5. SQL各种连接查询详解(左连接、右连接..)
  6. Doctype文档类型、作用及触发方式
  7. Effective C++笔记:设计与声明
  8. C#基本知识点-Readonly和Const的区别
  9. hdu 1325 Is It A Tree?
  10. Java远程方法调用(RMI)
  11. Hyper-V虚拟化--逻辑网络、VM网络、逻辑交换机
  12. ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题
  13. .net mvc 超过了最大请求长度 限制文件上传大小
  14. 《JS权威指南学习总结--第7章 数组》
  15. 【排序算法】快速排序算法 Java实现
  16. Spring Boot:如何优雅的使用 Mybatis
  17. python数据抓取分析(python + mongodb)
  18. Spring 整合 Quartz 实现动态定时任务
  19. eMMC基础技术6:eMMC data读写
  20. 在Vue中关闭Eslint 的方法

热门文章

  1. IOS6新特性之下拉刷新<UIRefreshControl>
  2. Hibernate 的Ehache学习
  3. ubuntu 16.04 完整安装 phantomjs
  4. Linux就业技术指导(五):Linux运维核心管理命令详解
  5. 获取Activity中得到焦点的EditText
  6. Django的模板语言介绍
  7. [leetcode]211. Add and Search Word - Data structure design添加查找单词 - 数据结构设计
  8. 'WebElement' object is not iterable
  9. CentOS 7安装Samba 4.6 版本步骤及错误解决方法
  10. Loitor_产品(二)校准立体摄像机