如何使用JAVA调用SHELL

通过ProcessBuilder进行调度

这种方法比较直观,而且参数的设置也比较方便, 比如我在实践中的代码(我隐藏了部分业务代码):

ProcessBuilder pb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, param1,
                        param2, param3);
    pb.directory(new File(SHELL_FILE_DIR));
    int runningStatus = 0;
    String s = null;
    try {
      Process p = pb.start();
      try {
        runningStatus = p.waitFor();
      } catch (InterruptedException e) {
      }

    } catch (IOException e) {
    }
    if (runningStatus != 0) {
    }
    return;

这里有必要解释一下几个参数:

RUNNING_SHELL_FILE:要运行的脚本
SHELL_FILE_DIR:要运行的脚本所在的目录; 当然你也可以把要运行的脚本写成全路径。
runningStatus:运行状态,0标识正常。 详细可以看java文档。
param1, param2, param3:可以在RUNNING_SHELL_FILE脚本中直接通过1,2,$3分别拿到的参数。

直接通过系统Runtime执行shell

这个方法比较暴力,也比较常用, 代码如下:

p = Runtime.getRuntime().exec(SHELL_FILE_DIR + RUNNING_SHELL_FILE + " "+param1+" "+param2+" "+param3);
p.waitFor();

我们发现,通过Runtime的方式并没有builder那么方便,特别是参数方面,必须自己加空格分开,因为exec会把整个字符串作为shell运行。

可能存在的问题以及解决方法

如果你觉得通过上面就能满足你的需求,那么可能是要碰壁了。你会遇到以下情况。

没权限运行

这个情况我们团队的朱东方就遇到了, 在做DTS迁移的过程中,要执行包里面的shell脚本, 解压出来了之后,发现执行不了。 那么就按照上面的方法授权吧

ProcessBuilder builder = new ProcessBuilder("/bin/chmod", "755", tempFile.getPath());
      Process process = builder.start();
      int rc = process.waitFor();

java进行一直等待shell返回

这个问题估计更加经常遇到。 原因是, shell脚本中有echo或者print输出, 导致缓冲区被用完了! 为了避免这种情况, 一定要把缓冲区读一下, 好处就是,可以对shell的具体运行状态进行log出来。 比如上面我的例子中我会变成:

ProcessBuilder pb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, keyword.trim(),
                        taskId.toString(), fileName);
    pb.directory(new File(CASPERJS_FILE_DIR));
    int runningStatus = 0;
    String s = null;
    try {
      Process p = pb.start();
      BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
      BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      while ((s = stdInput.readLine()) != null) {
        LOG.error(s);
      }
      while ((s = stdError.readLine()) != null) {
        LOG.error(s);
      }
      try {
        runningStatus = p.waitFor();
      } catch (InterruptedException e) {
      }

记得在start()之后, waitFor()之前把缓冲区读出来打log, 就可以看到你的shell为什么会没有按照预期运行。 这个还有一个好处是,可以读shell里面输出的结果, 方便java代码进一步操作。

(0)

相关推荐

  • 如何用java程序(JSch)运行远程linux主机上的shell脚本

    运行远程主机上的shell脚本 下面的例子是教给大家如何通过java程序,运行远程主机上的shell脚本.(我讲的不是一个黑客学习教程,而是使用用户名密码去执行有用户认证资格的主机上的shell脚本).并且通过java程序获得shell脚本的输出. 首先通过maven坐标引入JSch依赖库,我们正是通过JSch去执行远程主机上的脚本. <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch<

  • java调用shell命令并获取执行结果的示例

    使用到Process和Runtime两个类,返回值通过Process类的getInputStream()方法获取 package ark; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class ReadCmdLine { public st

  • Java程序去调用并执行shell脚本及问题总结(推荐)

    摘要: 该文章来自阿里巴巴技术协会(ATA)精选集 背景 我们在开发过程中,大部分是java开发, 而在文本处理过程中,主要就是脚本进行开发. java开发的特点就是我们可以很早地进行TDDL, METAQ 等等地对接: 而脚本开发的特点就是在进行批处理的时候非常方便. 背景 我们在开发过程中,大部分是java开发, 而在文本处理过程中,主要就是脚本进行开发. java开发的特点就是我们可以很早地进行TDDL, METAQ 等等地对接: 而脚本开发的特点就是在进行批处理的时候非常方便. 前阵子我

  • 详解Java使用Jsch与sftp服务器实现ssh免密登录

    一.什么是SFTP? SFTP是一个安全文件传送协议,可以为传输文件提供一种安全的加密方法.SFTP 为 SSH的一部份,是一种传输文件到服务器的安全方式.SFTP是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的.但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP. 二.什么是Jsch以及它的作用? Jsch是一个纯粹的用java实现SSH功能的java library.如果要知道Jsch的功

  • Java中通过jsch来连接远程服务器执行linux命令

    有时候你可能需要通过代码来控制执行linux命令实现某些功能. 针对这类问题可以使用JSCH来实现,具体代码如下: public class CogradientImgFileManager{ private static final Logger log = LoggerFactory.getLogger(CogradientImgFileManager.class); private static ChannelExec channelExec; private static Session

  • Java代码执行shell命令的实现

    本文描述两种方式使用java代码执行shell命令,首先使用Runtime类调用exce方法,其次使用ProcessBuilder实例实现更灵活的方式. 1. 环境准备 执行shell命令之前,我们需要获取jvm底层操作系统,同时定义通用消费流的类. 1.1. 操作系统依赖 在创建进场执行shell命令之前,我们需要获取jvm运行在具体哪个操作系统之上.因为Windows执行shell命令是cmd.exe,而其他操作系统发布标准shell是sh: boolean isWindows = Syst

  • java使用JSCH实现SFTP文件管理

    本文实例为大家分享了java使用JSCH实现SFTP文件管理的具体代码,供大家参考,具体内容如下 一.连接配置 1.在项目中导入jsch-0.1.51.jar包: 2.创建SFTP类,存放连接属性,其中要注意一点,在进行FTP操作时,一个会话在建立连接通道后进入A目录进行文件操作,不能直接跳到同级或上级目录操作,需要先退出当前会话或者新建会话. public class SFTP{ private Session session;//会话 private Channel channel;//连接

  • JAVA如何调用Shell脚本

    在实际项目中,Java有时候需要调用C写出来的东西,除了JNI以外,我认为一种比较好的方法是JAVA调用Shell.先把C写出来的make成可执行文件,然后再写一个shell脚本执行该可执行文件,最后是JAVA调用该shell脚本. JAVA调用很简单,例子如下: 首先是shell脚本 #!/bin/sh echo Begin word cluster /home/felven/word2vec/word2vec -train /home/felven/word2vec/resultbig.tx

  • Java工具jsch.jar实现上传下载

    在做运维的时候,我们一般使用shell脚本实现文件的服务器之间定时传输,那么对于一些不会shell脚本的童鞋,就得使用万能的编程语言了,这里我们介绍一款Java操作ftp的工具,那就是jsch.jar.工具已经写好,可以根据实际情况做调整,注释很清晰.大家按需阅读: package com.wdy.tools.utils.sftputil; import java.io.File; import java.io.FileInputStream; import java.io.FileOutput

  • Java调用Shell命令的方法

    本文实例讲述了Java调用Shell命令的方法.分享给大家供大家参考.具体如下: 近日项目中有这样一个需求:系统中的外币资金调度完成以后,要将调度信息生成一个Txt文件,然后将这个Txt文件发送到另外一个系统(Kondor)中.生成文件自然使用OutputStreamWirter了,发送文件有两种方式,一种是用写个一个类似于FTP功能的程序,另外一种就是使用Java来调用Shell,在Shell中完成文件的发送操作.我们选择后一种,即当完成外币资金的调度工作后,用Java的OutputStrea

  • 利用Python+Java调用Shell脚本时的死锁陷阱详解

    前言 最近有一项需求,要定时判断任务执行条件是否满足并触发 Spark 任务,平时编写 Spark 任务时都是封装为一个 Jar 包,然后采用 Shell 脚本形式传入所需参数执行,考虑到本次判断条件逻辑复杂,只用 Shell 脚本完成不利于开发测试,所以调研使用了 Python 和 Java 分别调用 Spark 脚本的方法. 使用版本为 Python 3.6.4 及 JDK 8 Python 主要使用 subprocess 库.Python 的 API 变动比较频繁,在 3.5 之后新增了

  • Java调用Shell命令和脚本的实现

    1.介绍 有时候我们在Linux中运行Java程序时,需要调用一些Shell命令和脚本.而Runtime.getRuntime().exec()方法给我们提供了这个功能,而且Runtime.getRuntime()给我们提供了以下几种exec()方法: Process exec(String command) 在单独的进程中执行指定的字符串命令. Process exec(String[] cmdarray) 在单独的进程中执行指定命令和变量. Process exec(String[] cmd

  • java调用shell脚本及注意事项说明

    目录 需求 问题 介绍 1.通过ProcessBuilder进行调度 2.直接通过系统的Runtime类执行shell 遇到的问题 1.没权限运行 2.调用shell脚本提示:No such file or directory 3.shell脚本输出太大,程序卡死问题 下面提供工具类和自己的shell脚本 工具类 shell脚本 需求 get方法下载远程zip包,然后zip包解压,取出第一级目录再次进行压缩获取新的压缩zip包. 问题 如果选择使用java代码的IO流操作,在不确定zip包大小的

  • Java调用shell脚本解决传参和权限问题的方法

    1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 shell命令 代码如下(此代码是存在问题的.完整代码请看2): /** * 执行shell * @param execCmd 使用命令 或 脚本标志位 * @param para 传入参数 */ private static void execShell(boolean execCmd, String

  • 如何使用JAVA调用SHELL

    通过ProcessBuilder进行调度 这种方法比较直观,而且参数的设置也比较方便, 比如我在实践中的代码(我隐藏了部分业务代码): ProcessBuilder pb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, param1, param2, param3); pb.directory(new File(SHELL_FILE_DIR)); int runningStatus = 0; String s = null; try {

  • Java远程调用Shell脚本并获取输出信息【推荐】

    1.添加依赖 <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId&g

  • Spring Boot调用 Shell 脚本实现看门狗功能

    需要实现看门狗功能,定时检测另外一个程序是否在运行,使用 crontab 仅可以实现检测程序是否正在运行,无法做到扩展,如:手动重启.程序升级(如果只需要实现自动升级功能可以使用 inotify)等功能:最后决定使用 Spring Boot 调用 Shell 脚本来实现 一.脚本 1.1 启动脚本 #!/bin/bash ps -ef | grep "demo-app-0.0.1-SNAPSHOT.jar" | grep -v "grep" if [ "$

随机推荐