接着之前写的一篇文章,《Linux的cached和pagecache清除 解决缓存、内存不足、测试结果影响问题》说的缓存影响测试的问题。找到了解决方法,开始实施~

测试用例使用java写的,需要再两个不同的用例之间调用一次

sync && echo 3 > /proc/sys/vm/drop_caches

这就等同于:

Java程序运行时,调用系统提供的服务:Linux脚本或者命令

这里不得不提到java的Process类、Runtime类。

1、Process是一个抽象类,封装了一个进程(在调用Linux的命令或者shell脚本就是为了执行一个在Linux下执行的程序)。

Process类提供了执行从进程输入,执行输出到进程,等待进程完成,检查进程的推出状态,以及shut down掉进程。它的所有标准 io(即 stdin、stdout 和 stderr)操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。

2、Runtime类,Runtime类是一个与JVM运行时环境有关的类,提供获取当前运行环境的接口,这个类是Singleton的。

其中的Runtime.getRuntime()方法作用是取得当前JVM的运行环境,也是java中唯一可以得到运行环境的方法。(另外,Runtime的大部分方法都是实例方法,也就是说每次运行调用的时候都需要调用到getRuntime方法)

再来说Runtime的exec()方法。

exec函数具体实现形式有以下几种:

</pre><pre name="code" class="java">Process exec(String command)   
         在单独的进程中执行指定的字符串命令。  
Process exec(String command, String[] envp)   
         在指定环境的单独进程中执行指定的字符串命令。  
Process exec(String command, String[] envp, File dir)   
         在有指定环境和工作目录的独立进程中执行指定的字符串命令。  
Process exec(String[] cmdarray)   
         在单独的进程中执行指定命令和变量。   
Process exec(String[] cmdarray, String[] envp)   
         在指定环境的独立进程中执行指定命令和变量。   
Process exec(String[] cmdarray, String[] envp, File dir)   
         在指定环境和工作目录的独立进程中执行指定的命令和变量。



注1:

command:一条指定的系统命令。

envp:环境变量字符串数组,其中每个环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为null。

dir:子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为null。

cmdarray:包含所调用命令及其参数的数组。数组的第一个元素是要执行的命令往后依次都是命令的参数。

注2:

Runtime.getRuntime().exec()这种调用方式在java虚拟机中是十分消耗资源的,即使命令可以很快的执行完毕,频繁的调用时创建进程消耗十分客观。

java虚拟机执行这个命令的过程是,首先克隆一条和当前虚拟机拥有一样环境变量的进程,再用这个新的进程执行外部命令,最后退出这个进程。频繁的创建对CPU和内存的消耗很大

下面上几个例子:

public class test {  
    public static void main(String[] args){  
        InputStream in = null;  
        try {  
            Process pro = Runtime.getRuntime().exec(new String[]{"sh",  
                                     "/home/test/test.sh","select admin from M_ADMIN",  
                                     "/home/test/result.txt"});  
            pro.waitFor();  
            in = pro.getInputStream();  
            BufferedReader read = new BufferedReader(new InputStreamReader(in));  
            String result = read.readLine();  
            System.out.println("INFO:"+result);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}


在这用了Process exec(String[] cmdarray)这个方法

 附/home/test/test.sh脚本如下:


1. #!/bin/sh  
2.   
3. #查询sql  
4. SQL=$1  
5. #查询结果保存文件  
6. RESULT_FILE=$2  
7. #数据库连接  
8. DB_NAME=scott  
9. DB_PWD=tiger  
10. DB_SERVER=DB_TEST  
11.   
12. RESULT=`sqlplus -S ${DB_NAME}/${DB_PWD}@${DB_SERVER}<< !   
13. set heading off  
14. set echo off  
15. set pages 0  
16. set feed off  
17. set linesize 3000  
18. ${SQL}  
19. /  
20. commit  
21. /  
22. !`  
23.       
24. echo "${RESULT}" >> ${RESULT_FILE}  
25. echo 0;

特别注意:当需要执行的linux命令带有管道符时(例如:ps -ef|grep java),用上面的方法是不行的,解决方式是将需要执行的命令作为参数传给shell 如:


1. public class Test {  
2. public static void main(String[] args) throws Exception{  
3. "/bin/sh","-c","ps -ef|grep java"};  
4.         Process pro = Runtime.getRuntime().exec(cmds);  
5.         pro.waitFor();  
6.         InputStream in = pro.getInputStream();  
7. new BufferedReader(new InputStreamReader(in));  
8. null;  
9. while((line = read.readLine())!=null){  
10.             System.out.println(line);  
11.         }  
12.     }
  1. }  

再如 :在Linux下执行命令:sh test.sh 

1、shpath:是/test/test.sh也就是我们要执行的sh脚本的完整路径+脚本名称

2、var是一个参数,可以有也可以没有,当然这个参数取决于你的sh脚本中是否使用到了这个参数,因为我的脚本中使用到了这个var参数,在Linux下面执行的时候是 sh test.sh  a.tar

这个var参数就是a.tar这个tar包的名字。

String command1 = “chmod 777 ” + shpath;
    process= Runtime.getRuntime().exec(command1);
    process.waitFor();
    Stringvar= “a.tar”;
    Stringcommand2 = “/bin/sh ” + shpath + ” ” + var;
    Runtime.getRuntime().exec(command2).waitFor();



String command1 = “chmod 777 ” + shpath; 
     process= Runtime.getRuntime().exec(command1);
     process.waitFor();
     Stringvar= “a.tar”;
     Stringcommand2 = “/bin/sh ” + shpath + ” ” + var;
     Runtime.getRuntime().exec(command2).waitFor();

注:

如果没有给这个sh文件添加权限(chmod777),就会执行到Runtime.getRuntime().exec的时侯会出现Permission denied错误。

waitFor()这个也是必不可缺的,等待进程执行完毕。如果你需要执行多行命令的话,把waitFor()这个加上。