ssh远程调用之shell脚本远程调用应用程序

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

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

原文地址:https://www.cnblogs.com/GatsbyNewton/p/4776682.html