如何在java中使用Process Builder来运行Linux shell命令?

时间:2017-06-19 19:00:10

标签: java shell processbuilder

我正在尝试使用JAVA程序执行两个linux命令:

  1. 的ifconfig | grep -A 1'eth0'| tail -1 | cut -d':' - f 2 | cut -d'' - f 1
  2. 这个命令给我和“IP地址”,我必须在第二个命令

    中阅读和使用它
    1. ./cuteTest.sh“IP地址”
    2. 我用来运行这些命令的功能是:

      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)
      

      有人能帮助我找出我在这里做错了吗?

1 个答案:

答案 0 :(得分: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,而 [{"time":"2017-03-23T12:23:05","user":"randomUser","action":"sleeping"}] [{"time":"2017-03-23T12:24:05","user":"randomUser","action":"sleeping"}] [{"time":"2017-03-23T12:33:05","user":"randomUser","action":"sleeping"}] [{"time":"2017-03-23T15:33:05","user":"randomUser2","action":"eating"}] [{"time":"2017-03-23T15:33:06","user":"randomUser2","action":"eating"}] 将调用复杂命令。