下文所述的两个试验在Linux AS3和Jdk5上测试通过。
一、在java程序中跨平台运行shell命令或者脚本,并获得其输出
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class TestCMD {
/**
* @param args
*/
public static void main(String[] args) {
try {
Process child = null;
String systemType = System.getProperty("os.name");
if (systemType.equals("Linux")) {
System.out.println("Linux OS!");
child = Runtime.getRuntime().exec("jmap -h", null, null);
} else if (systemType.indexOf("Windows") > -1) {
// If the os is windows, you need to add cmd before command.
System.out.println("Windows OS!");
child = Runtime.getRuntime().exec("cmd java -version", null,
null);
}
// Get the input stream and read from it
BufferedReader in = new BufferedReader(new InputStreamReader(child
.getInputStream()));
String c = null;
while ((c = in.readLine()) != null) {
System.out.println(c);
}
in.close();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
二、推广:根据某个进程特殊的tag获得其进程ID
import java.io.BufferedReader;
import java.io.InputStreamReader;
/*
* @(#)TestGetPid.java 2008-5-21
*
* Copyright (c) 2008
* All rights reserved.
* $
*/
/**
* <strong>Purpose:</strong><br>
* TODO.
*
* @version 1.0.1 2008-5-21<br>
* @author AxisThinker<br>
* @email
ddjoke@163.com
*/
public class TestGetPid {
/**
* @param args
*/
public static void main(String[] args) {
try {
Process child = null;
String systemType = System.getProperty("os.name");
if (systemType.equals("Linux")) {
// If the os is linux, you need to add bash before command.
System.out.println("Support Linux os!");
child = Runtime.getRuntime().exec("ps -Af", null, null);
} else if (systemType.indexOf("Windows") > -1) {
System.out.println("Not support windows!");
}
// Get the input stream and read from it
BufferedReader in = new BufferedReader(new InputStreamReader(child
.getInputStream()));
String c = null;
// Only get the first line of bash's output.
while ((c = in.readLine()) != null) {
//这里this.name=GOS.CORE就是我要找的某个进程的特殊tag,各位可以换成你想找的进程
if (c.contains("this.name=GOS.CORE")) {
c = c.substring(c.indexOf(" "), c.length());
c = c.trim();
c = c.substring(0, c.indexOf(" "));
c = c.trim();
System.out.println(c);
break;
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
三: 高级应用: 通过ssh的配置,远程调用其他主机的命令,并在本地得到其输出,中间不用输入密码
第一步:需要配置ssh。配置方法简要如下:
首先,例如我想用本地的lxy账户登陆远程节点A的lxy1账户,那么首先进入本地/home/lxy目录,在这个目录下有一个隐藏目录.ssh,进入这个目录,利用ssh-keygen命令来生成本用户的公私钥对,可以利用-t参数来指定生成方法:一般用rsa方法。此时,会要求你输入key的密码,直接回车就可以。如果你输的话,就一定要输入4位以上的密码,而且,以后你用ssh的时候就要输入这个密码。所以,建议不输入。
然后会在.ssh目录下生成两个文件,例如id_rsa和id_rsa.pub,利用vi拷贝id_rsa.pub中的内容到远程节点A的lxy1账户目录下的.ssh目录里面的authorized_keys文件里。这样,以后你在本地以lxy用户身份利用ssh命令用节点A的lxy1账号登陆A节点,就不用再输入密码了。而且,执行:ssh
lxy1@A ls 就能直接返回远程节点A的/home/lxy1/目录结构,不用输入密码。
第二步:编写程序
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
*Author: AxisThinker
*Email:
ddjoke@163.com
*/
public class TestCMD {
/**
* @param args
*/
public static void main(String[] args) {
try {
Process child = null;
String systemType = System.getProperty("os.name");
if (systemType.equals("Linux")) {
System.out.println("Linux OS!");
child = Runtime
.getRuntime()
.exec(
"ssh
gos@10.61.0.215 bash -c \"$JAVA_HOME/bin/jmap -heap 10191\"");
//这里有两点需要注意:第一你要运行的命令需要用bash -c引导。这样是告诉shell,后面的是一条指令,并且要在远端解释环境变量;二是要用转义\"来讲这个指令包起来,否则的话远端会以为jmap是一个指令,-heap是一个指令等等。
} else if (systemType.indexOf("Windows") > -1) {
// If the os is windows, you need to add cmd before command.
System.out.println("Windows OS!");
child = Runtime.getRuntime().exec(
new String[] { "cmd", "java", "-version" }, null, null);
}
// Get the input stream and read from it
BufferedReader in = new BufferedReader(new InputStreamReader(child
.getInputStream()));
String c = null;
while ((c = in.readLine()) != null) {
System.out.println(c);
if (c.equals("XXX")) {//这里比较重要,由于c = in.readLine()容易发生阻塞,所以,这里用比较土的办法来解决,根据最后一行的返回值来决定其是否退出。
break;
}
}
in.close();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
本文作者:网友 来源:其它 |
CIO之家 www.ciozj.com 微信公众号:imciow