2017-06-19 436 views
0

我想执行使用两个Linux命令JAVA程序:如何在java中使用Process Builder来运行Linux shell命令?

  1. 使用ifconfig | grep -A 1'eth0'| tail -1 | cut -d':'-f 2 | cut -d''-f 1

这条命令给我和“IP地址”,我必须阅读并且在第二命令中使用它

  • ./executeTest.sh“IP地址”
  • 我的功能,其我使用运行这些命令是这样的:

    public int exec(String[] command, Map<String, String> envt, StringBuilder stdout, StringBuilder stderr, int timeoutSeconds) throws TimeoutException, Exception{ 
         int exitValue = -1; 
         final File stdoutFile = File.createTempFile("test_", "extproc.out"); 
         final File stderrFile = File.createTempFile("test_", "extproc.err"); 
         Process process = null; 
         try{  
          ProcessBuilder pb = new ProcessBuilder(command); 
          if(envt!=null){ 
           for(Entry<String, String> entry : envt.entrySet()){ 
            pb.environment().put(entry.getKey(), entry.getValue()); 
           } 
          } 
          pb.redirectOutput(stdoutFile); 
          pb.redirectError(stderrFile); 
    
          process = pb.start(); 
    
          boolean timedOut = false; 
    
          timedOut = !(process.waitFor(timeoutSeconds, TimeUnit.SECONDS)); 
    
          if(timedOut){ 
           System.out.println("Timed out waiting for process to complete."); 
           try{  
            process.destroyForcibly(); 
           }catch(Exception killEx){ 
            System.out.println("Error while terminating runaway process"+ killEx); 
           } 
          }else{ 
           exitValue = process.exitValue();  
          } 
    
          stdout.append(FileUtils.readFileToString(stdoutFile)); 
          stderr.append(FileUtils.readFileToString(stderrFile)); 
    
          if(timedOut){ 
           throw new TimeoutException(); 
          } 
         }finally{ 
          if(stdoutFile.exists()){ 
           //File.deleteDirectory(stdoutFile); 
          } 
          if(stderrFile.exists()){ 
           //FileUtils.deleteDirectory(stdoutFile); 
          } 
          if(process != null){ 
           process.destroy(); 
          } 
    
         } 
         return exitValue; 
        } 
    

    但是,我越来越以下错误,当我把这个功能您在上面写的命令:

    java.io.IOException: Cannot run program "ifconfig | grep -A 1 'eth0' | tail -1 |cut -d ':' -f 2 |cut -d ' ' -f 1": error=2, No such file or directory 
         at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) 
         at IOxUnifiedSanityTestSuite.starWebServer.exec(starWebServer.java:66) 
         at IOxUnifiedSanityTestSuite.starWebServer$2.handle(starWebServer.java:148) 
         at IOxUnifiedSanityTestSuite.starWebServer$2.handle(starWebServer.java:124) 
         at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:217) 
         at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78) 
         at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:133) 
         at io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:79) 
         at io.vertx.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:288) 
         at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:421) 
         at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:134) 
         at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:623) 
         at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:573) 
         at io.vertx.core.http.impl.VertxHttpHandler.lambda$channelRead$0(VertxHttpHandler.java:71) 
         at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:322) 
         at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:190) 
         at io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:71) 
         at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:122) 
         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) 
         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) 
         at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) 
         at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) 
         at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) 
         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) 
         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) 
         at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) 
         at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) 
         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) 
         at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) 
         at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) 
         at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129) 
         at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642) 
         at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565) 
         at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479) 
         at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441) 
         at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) 
         at java.lang.Thread.run(Thread.java:745) 
    Caused by: java.io.IOException: error=2, No such file or directory 
         at java.lang.UNIXProcess.forkAndExec(Native Method) 
         at java.lang.UNIXProcess.<init>(UNIXProcess.java:248) 
         at java.lang.ProcessImpl.start(ProcessImpl.java:134) 
         at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029) 
         ... 36 more 
    
    
    The way I am calling exec function is this: 
    
    
    
        String command1[] = new String[]{"ifconfig | grep -A 1 \'eth0\' | tail -1 |cut -d \':\' -f 2 |cut -d \' \' -f 1"}; 
         StringBuilder stdout = new StringBuilder(); 
         StringBuilder stderr = new StringBuilder(); 
         exec(command1, null, stdout, stderr, 30) 
    
        String command2[] = new String[]{"./executeTest.sh ipaddress"}; 
        StringBuilder stdout1 = new StringBuilder(); 
        StringBuilder stderr1 = new StringBuilder(); 
        exec(command2, null, stdout1, stderr1, 30) 
    

    谁能帮我找到了什么,我做错了什么?

    +0

    请告诉你怎么称呼你的'exec' –

    +0

    你可以从'java.net.NetworkInterface.getNetworkInterfaces(任何或全部)你自己的IP地址()'更有效地比运行6个程序 –

    回答

    1

    你可能养活你的第一个命令作为一个整体来ProcessBuilder的构造:

    "ifconfig| grep -A 1 'eth0'|tail -1|cut -d ':' -f 2|cut -d ' ' -f 1" 
    

    ProcessBuilder认为它是一个程序的名字,因此错误。

    尝试传递给它下面的:

    new String{"/bin/bash", "-c", "ifconfig| grep -A 1 'eth0'|tail -1|cut -d ':' -f 2|cut -d ' ' -f 1"} 
    

    exec(new String{"/bin/bash", "-c", "ifconfig| grep -A 1 'eth0'|tail -1|cut -d ':' -f 2|cut -d ' ' -f 1"}, 
        envt, stdout, stderr, timeoutSeconds); 
    

    ProcessBuilder将调用bash,这反过来将调用复杂的命令。

    +0

    对于第二个命令,其中我想要触发shell脚本,该怎么做?如果我在第二个命令中添加“/ bin/bash”,“-c”来触发我的shell脚本,函数返回代码127. – user122345656

    +0

    需要'new String [] {“this”,“that”,“ etc“} –

    +0

    对于第二个命令,通常的'new String [] {”./executeTest.sh“,”1.2.3.4“}应该可以工作。 –