• Java程序执行Linux命令

    2014-02-20 23:49:50
    java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例, 该实例可用来控制进程并获得...

    java程序中要执行linux命令主要依赖2个类:Process和Runtime

    首先看一下Process类:

    ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,
    该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、
    检查进程的退出状态以及销毁(杀掉)进程的方法。
    创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows
    上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)
    操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。
    父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,
    如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
    当没有 Process 对象的更多引用时,不是删掉子进程,而是继续异步执行子进程。
    对于带有 Process 对象的 Java 进程,没有必要异步或并发执行由 Process 对象表示的进程。
    

    特别需要注意的是:

    1,创建的子进程没有自己的终端控制台,所有标注操作都会通过三个流

    (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程(父进程可通过这些流判断子进程的执行情况

    2,因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,

    则可能导致子进程阻塞,甚至产生死锁

    abstract  void destroy() 
              杀掉子进程。 
    abstract  int exitValue() 
              返回子进程的出口值。根据惯例,值0表示正常终止。 
    abstract  InputStream getErrorStream() 
              获取子进程的错误流。 
    abstract  InputStream getInputStream() 
              获取子进程的输入流。 
    abstract  OutputStream getOutputStream() 
              获取子进程的输出流。 
    abstract  int waitFor() 
              导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。
     	 如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程。

    特别需要注意:如果子进程中的输入流,输出流或错误流中的内容比较多,最好使用缓存(注意上面的情况2)

    再来看一下Runtime类:

    每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime方法获取当前运行时环境。 
    应用程序不能创建自己的Runtime类实例。 

    介绍几个主要方法:

     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) 
              在指定环境和工作目录的独立进程中执行指定的命令和变量。 
    

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

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

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

    cmdarray:包含所调用命令及其参数的数组。

    以下为示例(要打成可执行jar包扔到linux下执行):

    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脚本如下:

    #!/bin/sh
    
    #查询sql
    SQL=$1
    #查询结果保存文件
    RESULT_FILE=$2
    #数据库连接
    DB_NAME=scott
    DB_PWD=tiger
    DB_SERVER=DB_TEST
    
    RESULT=`sqlplus -S ${DB_NAME}/${DB_PWD}@${DB_SERVER}<< ! 
    set heading off
    set echo off
    set pages 0
    set feed off
    set linesize 3000
    ${SQL}
    /
    commit
    /
    !`
    	
    echo "${RESULT}" >> ${RESULT_FILE}
    echo 0;
    

    特别需要注意的是,当需要执行的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);
    		}
    	}
    }


    PS:

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

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


    展开全文
  • Java执行Linux命令

    2018-05-16 13:10:05
    最近工作中需要在Java中执行Linux命令,对遇到的坑做一个小结。API把要执行的命令作为exec方法的参数,返回一个Process对象代表命令执行的进程。由于执行完命令通常要获取输出显示出来,因此对执行命令并获取输出的...

    最近工作中需要在Java中执行Linux命令,对遇到的坑做一个小结。

    API


    把要执行的命令作为exec方法的参数,返回一个Process对象代表命令执行的进程。由于执行完命令通常要获取输出显示出来,因此对执行命令并获取输出的过程封装为一个工具类:

    CommandUtil

    package org.ml.deployer.util;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Scanner;
    import java.util.concurrent.TimeUnit;
    
    public class CommandUtil {
    	public static String run(String command) throws IOException {
    		Scanner input = null;
    		String result = "";
    		Process process = null;
    		try {
    			process = Runtime.getRuntime().exec(command);
    			try {
    				//等待命令执行完成
    				process.waitFor(10, TimeUnit.SECONDS);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			InputStream is = process.getInputStream();
    			input = new Scanner(is);
    			while (input.hasNextLine()) {
    				result += input.nextLine() + "\n";
    			}
    			result = command + "\n" + result; //加上命令本身,打印出来
    		} finally {
    			if (input != null) {
    				input.close();
    			}
    			if (process != null) {
    				process.destroy();
    			}
    		}
    		return result;
    	}
    	
    	public static String run(String[] command) throws IOException {
    		Scanner input = null;
    		String result = "";
    		Process process = null;
    		try {
    			process = Runtime.getRuntime().exec(command);
    			try {
    				//等待命令执行完成
    				process.waitFor(10, TimeUnit.SECONDS);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			InputStream is = process.getInputStream();
    			input = new Scanner(is);
    			while (input.hasNextLine()) {
    				result += input.nextLine() + "\n";
    			}
    			result = command + "\n" + result; //加上命令本身,打印出来
    		} finally {
    			if (input != null) {
    				input.close();
    			}
    			if (process != null) {
    				process.destroy();
    			}
    		}
    		return result;
    	}
    }

    示例:

    执行启动tomcat的脚本:


    执行结果:


    执行带特殊字符的命令

    exec方法无法执行带 | > 等特殊字符的命令,如 ps -ef | grep java 。

    此时要把整个命令作为 /bin/sh 的参数执行,如:


    注意

    exec方法通过创建一个子进程执行Linux命令,因此频繁地通过Java调用Linux命令对性能影响非常大,不要在程序中过度使用这种方式。

    展开全文
  • java,linux转义字符区别

    2016-10-09 17:44:33
    java,linux转义字符区别

    java转义字符为反斜杠\,是将普通字符转化为特殊有有意义的字符,如n字母加上\变为\n,就是换行符,\r,\t都是被转义后的字符。

    /则是表示路径,例如:d:/text.txt或d://text.txt

    使用时出现问题:

    java中String字符串使用split切割字符串时的问题,String str=“a|b|v”;

    而直接用split("|");是不行的。原因是竖线 | 在java正则中是将两个匹配条件进行逻辑“或”(Or)运算,因此需要将|转义,也就是 split(“\|”);

    但实际在java中使用时,\又是java的转义字符,需要转义,最终变成了split("\\|"),不过使用split("[|]")也可以达到效果,[]在JAVA正则中表示选择[]里面的一个字符。

    linux中\也代表转义字符,但是是将有特殊意义的字符转为普通字符,例如:.代表当前目录,使用\.转义后就是代表一个.

    ..代表上层目录,转义后就是\.\.就是两个..

    echo  $HOME 输出是家目录,转义后就是 echo \$HOME 输出为原样输出, $HOME




    展开全文
  • javaLinux与Windows路径分隔符问题在开发过程中,常常会遇到开发环境为Windows,而生产环境为Linux的情况。其中难免涉及读取文件的问题,而两者的转义符是有区别的。如果直接将Windows环境下执行通过的代码部署到...

    java中Linux与Windows路径分隔符

    问题

    在开发过程中,常常会遇到开发环境为Windows,而生产环境为Linux的情况。其中难免涉及读取文件的问题,而两者的转义符是有区别的。如果直接将Windows环境下执行通过的代码部署到Linux,则相应功能会报错,可写两套分别适应于不同环境的代码却太过麻烦。

    Windows

    java在Windows下的路径分隔符为反斜杠即‘\’。
    代码中需要有转义符,例如:

    String path = “D:\\tmp”;

    Linux

    java在Linux下的路径分隔符为正斜杠即’/’
    代码中无需转义符,例如:

    String path = “/data/tmp”;

    Java中的解决办法

    其实方法很简单,java.io.File下有一个静态String类型:separator,只要用它替换斜杠就能解决不同环境下文件系统的问题。

    String path = “D:”+File.separator+”tmp”;

    浅尝File.separator

    通过观察File.separator我们可以发现separator主要由一个separatorChar组成。

    public static final String separator = “” + separatorChar;

    继续查看separatorChar,发现其调用的是FileSystem的方法

    static private FileSystem fs = FileSystem.getFileSystem();
    public static final char separatorChar = fs.getSeparator();

    而在FileSystem中则调用了一个native方法,从这里就能得知当前的代码是处在什么文件系统下的了。

    public static native FileSystem getFileSystem();

    展开全文
  • Java 连接linux服务器

    2019-07-01 16:52:37
    Java 连接linux服务器 转载请标明出处^_^ 原文首发于:www.zhangruibin.com 本文出自于:RebornChang的博客 众所周知,linux服务器是支持ssh命令连接的,连接格式:ssh user@ipAddr port,回车之后输入密码即可...

    Java 连接linux服务器

    转载请标明出处^_^
    原文首发于:www.zhangruibin.com
    本文出自于:RebornChang的博客

    众所周知,linux服务器是支持ssh命令连接的,连接格式:ssh user@ipAddr port,回车之后输入密码即可连接。
    那么,怎样使用Java代码进行连接,并且执行命令呢?

    来了解一下什么是Jsch与ganymed-ssh2
    Ganymed SSH-2 for Java是用纯Java实现SSH-2协议的一个包。可以利用它直接在Java程序中连接SSH服务器。MVN地址为:https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2
    可以看到最后的更新日志为2014年。
    ganymed-ssh2和Jsch大同小异,不再多说,重点说下怎样在Java代码中连接linux。

    首先确认linux开启了ssh连接方式

    centos7下执行命令:
    ps -e | grep sshd

    若输出为:
    1132 ? 00:00:00 sshd
    10614 ? 00:00:02 sshd
    10616 ? 00:00:00 sshd
    10748 ? 00:00:00 sshd
    则证明开启了ssh服务,若没有以上输出,则需要开启ssh服务,开启方法:
    开启方法

    使用shell工具测试连接

    使用Xshell,secureCRT,FinallShell等工具进行连接测试。
    命令格式:ssh user@ipAddr port。
    测试效果如下图:

    主机上编写一个shell脚本用于测试

    在主机上编写一个简单的shell脚本用于测试。
    脚本名称为: testForJava ;
    脚本目录为:/test/shell;
    脚本内容:

    #!/bin/sh
    echo "If you can read this ,it means that you can conctrl server remote!"
    
    

    编辑完之后再服务器上本地测试效果如下图所示:

    Maven项目引入依赖编写Java代码测试

    这里说下maven的,非maven项目网上下载jar包引入。
    ganymed-ssh2的maven地址上文中已经说过了,在POM文件中加入相关依赖就行了,博文中加入的依赖为:

    <!-- https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2 -->
       	<dependency>
       		<groupId>ch.ethz.ganymed</groupId>
       		<artifactId>ganymed-ssh2</artifactId>
       		<version>build210</version>
       	</dependency>
    

    Java代码为:

    public class TestUseSSH {
       private static  String ip = "your ip";
       private static  int port = 22;
       private static  String user = "user";
       private static  String pswd = "pswd";
    
    
       public static void main(String[] args) {
           try {
    
               Connection conn = new Connection(ip,port);
               conn.connect();
               boolean isAuthenticated = conn.authenticateWithPassword(user,
                       pswd);
               if (isAuthenticated == false)
                   throw new IOException("Authentication failed.");
               Session sess = conn.openSession();
               sess.execCommand("sh /test/shell/testForJava");
               InputStream stdout = new StreamGobbler(sess.getStdout());
               BufferedReader br = new BufferedReader(
                       new InputStreamReader(stdout));
               while (true) {
                   String line = br.readLine();
                   if (line == null)
                       break;
                   System.out.println(line);
               }
               sess.close();
               conn.close();
           } catch (IOException e) {
               e.printStackTrace(System.err);
    
               System.exit(2);
           }
    
       }
    
    
    }
    
    

    运行后输出结果为:

    If you can read this ,it means that you can conctrl server remote!
    

    注:这里只说了linux下执行命令,更多功能在这里没有描述,有兴趣的可以自行深入探索,Over!

    展开全文
  • linux直接下载java

    2018-11-19 23:21:58
    因为Oracle官网下载java需要点击接受按钮,如果不接受就会被跳转 参考了一些文章之后,发现: 只要把点击确定后的的cookie复制下来,加到下载请求头里边就行,例如: wget --no-cookies --no-check-certificate --...
  • Linux上安装java

    2019-04-08 01:01:01
    一、Linux上安装.rpm二进制包的JDK. 3 1、JDK的下载... 3 (1)获取JDK的.rpm文件下载地址... 3 (2)wget下载文件到指定目录下并修改改文件名... 4 (3)在Linux上进行下载JDK的.rpm文件... 5 2、查看系统默认...
  • javalinux下新建文件夹
  • 我用Java写的复制文件功能,在windows下正常,在几个Linux机器上也正常,但有一个Linux机器上就复制不了,能有什么原因呢?我用cp命令行在这台机器上复制是可以的。 我刚开始学习LinuxJava,请大神们多多赐教啊...
  • Linux中配置java环境

    2019-07-14 14:28:35
    很多应用的运行需要有Java环境,如 tomcat 、amoeba 等。 首先查看自己的系统有没有安装java环境,查看命令: java -version 这里显示我们的 java 版本是1.7.0。有时候,我们的应用需要...
  • Linux Java程序debug总结

    2017-04-28 12:36:02
    使用Linux shell进行Java debug 使用jvisualvm 进行远程Java debug
  • 本文是2017年的第一篇博文,给大家带来一篇如何在Linux上以后台服务的方式运行Jar程序,好了,不多说了,祝大家在新的一年里学业进步,事业有成,我们直接进入主题吧。 Linux以后台服务方式运行Jar有两种方式,下面...
  • 目录 测试环境 下载JDK 终端模拟软件 安装前准备 tar包的安装方法 ...LInux系统版本:CentOS 7 64位 ...Java版本:jdk-8u181-linux-x64 下载JDK 下载地址: https://www.oracle.com/technetwork/jav...
  • linuxjava 使用 javasqlitehttp://www.ch-werner.de/javasqlite/1) 下载:http://www.ch-werner.de/javasqlite/javasqlite-20140624.tar.gz2) 解压后进入目录编译$ cd javasqlite-20140624$ ./configure$ make3) ...
  • Linux 下查看java进程

    2018-11-29 16:37:02
    Linux下查看和停止所有java进程 1.ps -ef | grep javaLinux下查看所有java进程命令:ps -ef | grep java 停止特定java进程命令:kill -9 java进程序号 停止所有java进程命令:pkill - 9 java 2.jps jps -l -v ...
  • linux下安装java

    2018-12-19 11:03:45
    1.首先要去下载好JDK,Java SE 8的官方网址是http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html   2 tar -zxvf jdk-8u102-linux-x64.tar.gz   3 然后我们来新建一个...
  • 关于Java文件路径在Windows和Linux中的问题~
  • linux中查看java进程

    2012-04-13 10:11:44
    [root@vm-linux-x86 ~]# ps -ef|grep java root 4834 1 2 Jun10 pts/6 03:10:50 /opt/JDK/jdk1.6.0_21/bin/java -classpath /opt/JReport/Server_B201106081302/derby/lib/*:/opt/JReport/Server_B2
  • linux重启java程序

    2017-10-23 22:05:26
    这篇文章主要讲解 linux重启java程序#!/bin/sh jarname='test-1.0' pid=`ps aux | grep $jarname | grep -v grep | awk '{print $2}'` echo $pid kill -9 $pid nohup java -jar $jarname.jar --spring.profiles....
  • 最开始的想法是使用Java做文件操作,遍历所有小文件然后往一个文件写(可以做成并发写),但是发现操作过程中遇到个问题,写一千多个小文件在本机Windows下需要花费几十秒的时间,即使在Linux环境下高配置的机器也...
1 2 3 4 5 ... 20
收藏数 742,104
精华内容 296,841
热门标签