对于以下命令:
ls /var/log/nginx/access.log.*
ls /var/log/nginx/access.log.* | grep 2011-05-16
grep "test=123&name=opencfg.com" /var/log/nginx/access.log.* > /root/alert.log
类似这样的命令,process.exec是不会理解其中的*号与> 甚至管道符号|
这是由于在linux环境下,我们一般使用bash shell调用这些命令, 而其中的一些符号 诸如:
*, ?, >, < , | 这样的符号是通过/bin/bash -c来做解释后再传递给 所调用的命令
/bin/bash -c 这个参数已经作为默认命令,在系统启动时加载到运行环境中,所以我们敲以上命令的时候可以省略
但对于java的Process来说,不会识别这些符号,因此我们必须强制调用/bin/bash -c来帮我们做符号解释:
下边是一段测试代码:
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- /**
- * CommandTest
- *
- * @author opencfg.com
- * @since 0.0.1-SNAPSHOT
- * @version 0.0.1-SNAPSHOT
- * @date 2011-05-17
- */
- public class CommandTest {
- public static void main(String[] args) throws Exception {
- // 1.test console args commands
- // exec("args", args);
- String[] commands = new String[] { "/bin/bash", "-c", "grep -h 200.*370.*http /var/log/nginx/access.log.* > /root/test_123.log" };
- String[] commands_ls = new String[] { "/bin/bash", "-c", "ls /var/log/nginx/access.log.*" };
- // 1.test java string commands
- exec("commands", commands);
- }
- public static void exec(String message, String[] args) throws Exception {
- print(message + ":");
- Process process = Runtime.getRuntime().exec(args);
- for (String arg : args) {
- System.out.println(arg);
- System.out.print(" ");
- }
- BufferedReader errorReader = new BufferedReader(new InputStreamReader(
- process.getInputStream()));
- String line = null;
- while ((line = errorReader.readLine()) != null) {
- System.err.println(line);
- }
- errorReader.close();
- BufferedReader infoReader = new BufferedReader(new InputStreamReader(
- process.getErrorStream()));
- while ((line = infoReader.readLine()) != null) {
- System.out.println(line);
- }
- infoReader.close();
- print("");
- }
- public static void print(String[] args) {
- for (String arg : args) {
- System.out.println(arg);
- System.out.print(" ");
- }
- }
- public static void print(String arg) {
- System.out.println(arg);
- }
- }
特别需要注意的是,当需要执行的linux命令带有管道符时(例如:ps -ef|grep java),用上面的方法是不行的,解决方式是将需要执行的命令作为参数传给shell
- public class Test {
- public static void main(String[] args) throws Exception{
- String[] cmds = {"/bin/sh","-c","ps -ef|grep java"};
- Process pro = Runtime.getRuntime().exec(cmds);
- pro.waitFor();
- InputStream in = pro.getInputStream();
- BufferedReader read = new BufferedReader(new InputStreamReader(in));
- String line = null;
- while((line = read.readLine())!=null){
- System.out.println(line);
- }
- }
- }
try
String[] commands = new
String[]{"find",".","-name","*mysql*","-print"};
Process process = Runtime.getRuntime().exec (commands);
InputStreamReader ir=new
InputStreamReader(process.getInputStream());
BufferedReader input = new BufferedReader (ir);
String line;
while ((line = input.readLine ()) != null){
System.out.println(line);
}//end try
catch (java.io.IOException e){
System.err.println ("IOException " + e.getMessage());
3) 执行一个自己写的脚本
非常简单,只需要在构造commands时写出它的详细路径和文件名,及参数等。
try
String commands = "/root/test/checkfile.sh";
Process process = Runtime.getRuntime().exec (commands);
InputStreamReader ir=new
InputStreamReader(process.getInputStream());
BufferedReader input = new BufferedReader (ir);
String line;
while ((line = input.readLine ()) != null){
System.out.println(line);
}//end try
catch (java.io.IOException e){
System.err.println ("IOException " + e.getMessage());
如果命令中有参数,同2)要用数组的形式。
import java.io.*;
import java.lang.*;class test3{
public static void main(String []args) throws IOException{
long a = System.currentTimeMillis();
Process process = Runtime.getRuntime().exec("/home/zhangdi/traceroute_l");//这是外部程序所在目录,切记返回类型为process
PrintStream outputWriter = new PrintStream(new BufferedOutputStream(process.getOutputStream()));
outputWriter.println("218.198.33.204");
outputWriter.flush();//这里一定要刷新缓冲区,不然参数传不过去
outputWriter.println("-T");
outputWriter.flush();
outputWriter.println("-80");
outputWriter.flush();
outputWriter.println("4");
outputWriter.flush();
outputWriter.println("192.168.1.30");
outputWriter.flush();
BufferedReader addResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line=addResult.readLine())!=null)
{
System.out.println(line);
}
long b = System.currentTimeMillis();
System.out.println(b-a);
}
}