java代码执行Linux脚本,java程序执行,调用shell命令和shell脚本

坑呀!记得在start()之后, waitFor()之前把缓冲区读出来打log,否则是阻塞缓冲区,没有输出的

package com.jikexueyuancrm.util;

import java.io.BufferedReader;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.lang.management.ManagementFactory;

import java.util.List;

import org.apache.log4j.Logger;

import com.jikexueyuancrm.controller.AnHui;

/**

* ShellUtils

Check root

{@link ShellUtils#checkRootPermission()}

Execte command

{@link ShellUtils#execCommand(String, boolean)}

{@link ShellUtils#execCommand(String, boolean, boolean)}

{@link ShellUtils#execCommand(List, boolean)}

{@link ShellUtils#execCommand(List, boolean, boolean)}

{@link ShellUtils#execCommand(String[], boolean)}

{@link ShellUtils#execCommand(String[], boolean, boolean)}

*

* @author Trinea 2013-5-16

*/

/**

* @author yuan hai

* 使用Runtime.getRuntime().exec

*/

public class ShellUtils {

private static Logger log = Logger.getLogger(ShellUtils.class);

public static final String COMMAND_SU       = "su";

public static final String COMMAND_SH       = "sh";

public static final String COMMAND_EXIT     = "exit\n";

public static final String COMMAND_LINE_END = "\n";

private ShellUtils() {

throw new AssertionError();

}

/**

* check whether has root permission

*

* @return

*/

public static boolean checkRootPermission() {

return execCommand("echo root", true, false).result == 0;

}

/**

* execute shell command, default return result msg

*

* @param command command

* @param isRoot whether need to run with root

* @return

* @see ShellUtils#execCommand(String[], boolean, boolean)

*/

public static CommandResult execCommand(String command, boolean isRoot) {

return execCommand(new String[] {command}, isRoot, true);

}

/**

* execute shell commands, default return result msg

*

* @param commands command list

* @param isRoot whether need to run with root

* @return

* @see ShellUtils#execCommand(String[], boolean, boolean)

*/

public static CommandResult execCommand(List commands, boolean isRoot) {

return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true);

}

/**

* execute shell commands, default return result msg

*

* @param commands command array

* @param isRoot whether need to run with root

* @return

* @see ShellUtils#execCommand(String[], boolean, boolean)

*/

public static CommandResult execCommand(String[] commands, boolean isRoot) {

return execCommand(commands, isRoot, true);

}

/**

* execute shell command

*

* @param command command

* @param isRoot whether need to run with root

* @param isNeedResultMsg whether need result msg

* @return

* @see ShellUtils#execCommand(String[], boolean, boolean)

*/

public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {

return execCommand(new String[] {command}, isRoot, isNeedResultMsg);

}

/**

* execute shell commands

*

* @param commands command list

* @param isRoot whether need to run with root

* @param isNeedResultMsg whether need result msg

* @return

* @see ShellUtils#execCommand(String[], boolean, boolean)

*/

public static CommandResult execCommand(List commands, boolean isRoot, boolean isNeedResultMsg) {

return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg);

}

/**

* execute shell commands

*

*

* 最基础方法

* @param commands command array

* @param isRoot whether need to run with root

* @param isNeedResultMsg whether need result msg

* @return 

*         

if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and

*         {@link CommandResult#errorMsg} is null.

*         

if {@link CommandResult#result} is -1, there maybe some excepiton.

*         

*/

public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {

int result = -1;

if (commands == null || commands.length == 0) {

return new CommandResult(result, null, null);

}

Process process = null;

BufferedReader succe***esult = null;

BufferedReader errorResult = null;

StringBuilder successMsg = null;

StringBuilder errorMsg = null;

DataOutputStream os = null;

try {

process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);

os = new DataOutputStream(process.getOutputStream());

for (String command : commands) {

if (command == null) {

continue;

}

// donnot use os.writeBytes(commmand), avoid chinese charset error

os.write(command.getBytes());

os.writeBytes(COMMAND_LINE_END);

os.flush();

}

os.writeBytes(COMMAND_EXIT);

os.flush();

// get command result

if (isNeedResultMsg) {

successMsg = new StringBuilder();

errorMsg = new StringBuilder();

succe***esult = new BufferedReader(new InputStreamReader(process.getInputStream()));

errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));

String s;

while ((s = succe***esult.readLine()) != null) {

successMsg.append(s).append("\n");

}

while ((s = errorResult.readLine()) != null) {

errorMsg.append(s).append("\n");

}

}

result = process.waitFor();

} catch (IOException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (os != null) {

os.close();

}

if (succe***esult != null) {

succe***esult.close();

}

if (errorResult != null) {

errorResult.close();

}

} catch (IOException e) {

e.printStackTrace();

}

if (process != null) {

process.destroy();

}

}

log.info("result:"+result);

if( successMsg != null) log.info("successMsg:"+successMsg.toString());

if( errorMsg != null) log.info("errorMsg:"+errorMsg.toString());

return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null

: errorMsg.toString());

}

/**

* result of command

{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in

* linux shell

{@link CommandResult#successMsg} means success message of command result

{@link CommandResult#errorMsg} means error message of command result

*

* @author Trinea 2013-5-16

*/

public static class CommandResult {

/** result of command **/

public int    result;

/** success message of command result **/

public String successMsg;

/** error message of command result **/

public String errorMsg;

public CommandResult(int result) {

this.result = result;

}

public CommandResult(int result, String successMsg, String errorMsg) {

this.result = result;

this.successMsg = successMsg;

this.errorMsg = errorMsg;

}

}

public static void main(String[] args) throws Exception {

//

String[] cmd=new String[]{"ps aux","pwd","ls -al"};

//执行shell命令

//    execCommand(cmd,false, true);

//执行shell脚本

String[] script=new String[]{"/bin/bash /home/smgadmin/test/soyoung_comment/shell/crawler.sh start  "};

execCommand(script,false, true);

//使用ProcessBuilder

//    exeCmd("ps aux;ls -al;pwd");//执行linux命令

//    exeCmd("dir&dir");//执行windows命令一行多命令用&分隔

}

//使用ProcessBuilder

/**

* @author yuan hai 2016年12月9日

* @param shell  shell可以传入多个命令  ,例如:"ps aux;ls -al;pwd"

* @return

* @throws IOException

*/

public  static int exeCmd(String shell) throws IOException {

int success = 0;

StringBuffer sb = new StringBuffer();

BufferedReader br = null;

// get name representing the running Java virtual machine.

String name = ManagementFactory.getRuntimeMXBean().getName();

String pid = name.split("@")[0];

try {

System.out.println("Starting to exec{ " + shell + " }. PID is: " + pid);

Process process = null;

//执行脚本时,不要加-c

// 当执行系统的命令时,才会加-c

//linux命令行

ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", shell);

//windows命令行

//  ProcessBuilder pb = new ProcessBuilder("cmd", "/c", shell);

pb.environment();

pb.redirectErrorStream(true); // merge error stream into standard stream

process = pb.start();

if (process != null) {

br = new BufferedReader(

new InputStreamReader(process.getInputStream(),"GBK"), 1024);

} else {

System.out.println("There is no PID found.");

}

sb.append("Ending exec right now, the result is:\n");

String line = null;

while (br != null && (line = br.readLine()) != null) {

sb.append(line).append("\n");

}

//记得在start()之后, waitFor()之前把缓冲区读出来打log

process.waitFor();

} catch (Exception ioe) {

sb.append("Error occured when exec cmd:\n").append(ioe.getMessage()).append("\n");

} finally {

PrintWriter writer = null;

if (br != null) {

br.close();

}

try {

writer = new PrintWriter(System.out);

writer.write(sb.toString());

} catch (Exception e) {

log.error(e.getMessage(), e);

} finally {

writer.close();

}

success = 1;

}

return success;

}

}

参考文章:

阿里大牛文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以通过Runtime和ProcessBuilder类来调用Shell命令脚本。下面是一个简单的示例: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ShellCommand { public static void main(String[] args) { try { // 执行Shell命令 Process process = Runtime.getRuntime().exec("ls -al"); // 读取Shell命令的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待Shell命令执行完毕 int exitCode = process.waitFor(); System.out.println("Shell命令执行完毕,退出码为:" + exitCode); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在上述示例中,我们通过Runtime类的exec()方法执行了一个Shell命令,然后通过Process类的getInputStream()方法获取了Shell命令的输出流,并通过BufferedReader类逐行读取了输出内容。最后,我们通过Process类的waitFor()方法等待Shell命令执行完毕,并获取了Shell命令的退出码。 类似地,我们也可以使用ProcessBuilder类来执行Shell脚本。以下是一个示例: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; public class ShellScript { public static void main(String[] args) { try { // 执行Shell脚本 ProcessBuilder builder = new ProcessBuilder(Arrays.asList("/bin/bash", "-c", "./test.sh")); Process process = builder.start(); // 读取Shell脚本的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待Shell脚本执行完毕 int exitCode = process.waitFor(); System.out.println("Shell脚本执行完毕,退出码为:" + exitCode); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在上述示例中,我们使用ProcessBuilder类创建了一个Shell进程,并指定了要执行Shell脚本。然后通过Process类的getInputStream()方法获取了Shell脚本的输出流,并通过BufferedReader类逐行读取了输出内容。最后,我们通过Process类的waitFor()方法等待Shell脚本执行完毕,并获取了Shell脚本的退出码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值