如何在java中使用Process Builder运行Linux shell命令?
我正在尝试使用JAVA程序执行两个linux命令: ifconfig | grep-a1'eth0'| tail-1 | cut-d':'-f2 | cut-d'-f1 这个命令给出了我的地址和IP地址,我必须在第二个命令中读取并使用它 ./executeTest.sh IP地址 我用来运行这些命令的函数是:如何在java中使用Process Builder运行Linux shell命令?,java,shell,processbuilder,Java,Shell,Processbuilder,我正在尝试使用JAVA程序执行两个linux命令: ifconfig | grep-a1'eth0'| tail-1 | cut-d':'-f2 | cut-d'-f1 这个命令给出了我的地址和IP地址,我必须在第二个命令中读取并使用它 ./executeTest.sh IP地址 我用来运行这些命令的函数是: public int exec(String[] command, Map<String, String> envt, StringBuilder stdout, String
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)
有人能帮我找出我做错了什么吗?您可能会将第一个命令作为一个整体提供给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"}
像
ProcessBuilder将调用bash,bash反过来将调用复杂命令。请说明如何调用execute。与运行6个程序相比,从java.net.NetworkInterface.getNetworkInterfaces获取任何或所有IP的效率更高。对于第二个要触发shell脚本的命令,该怎么做?如果我在第二个命令中添加/bin/bash,-c以触发shell脚本,那么函数将返回代码127.need数组说明符,格式为新字符串[]{this,that,etc}。对于第二个命令,通常的`new String[]{./executeTest.sh,1.2.3.4}应该可以工作。
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);