java exec shell_通过Java代码执行shell命令/脚本

JDK自带的两种方式有通过Runtime.getRuntime().exec()和ProcessBuilder类来做, 后者是JDK1.5以后引入的,官方也建议放弃使用Runtime的方式来做。今天在实现的时候就是采用ProcessBuilder,apache commons类库也提供了一个exec包专门做这类功能,这次暂时没用到。

在编写过程中,遇到几个比较坑的地方:

1、构建ProcessBuilder采用的参数:

建议采用“/bin/bash”. "-c",  "your shell"组装一个List, 其实你一次如果执行多个命令,都可以统一放到那个“your shell”字符串中。

2、执行过程中输出流控制:

在执行过程中,我们肯定需要得到正常的执行结果,也需要知道出错的内容提示, 这时需要将错误输出流重定向到标准输出流,相当于合并在一起输出

3、有些命令是需要环境变量的支持, 这时需要执行evivonment()拷贝系统相关env变量到当前进程上下文中,供命令使用。

4、如果执行过程卡死,需要知道可以kill哪个进程, 所以输出内容中将当前进程ID打印出,便于手动处理。

完整代码如下:

public 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;

ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-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()), 1024);

process.waitFor();

} 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");

}

} 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
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值