【问题标题】:Execute shell command with `java.lang.ProcessBuilder`使用 `java.lang.ProcessBuilder` 执行 shell 命令
【发布时间】:2016-05-01 12:13:04
【问题描述】:

我在CFML中编写了以下执行shell命令的小脚本,我的问题是输出,只要输出是单行就可以,如果是多行我只得到第一行,我试过了在脚本上做一个 while 循环(在代码上注释)但不起作用,Java 抛出内存错误java.lang.OutOfMemoryError: Java heap space。我能做什么?

<cfscript>
  str = ":>exec uname";
  exec_init=str.split(":>exec ");
  exec=exec_init[2].split(" ");
  p = createObject("java","java.lang.ProcessBuilder").init(exec).start();
  i = createObject("java","java.io.InputStreamReader").init(p.getInputStream());
  br = createObject("java","java.io.BufferedReader").init(i);
  line=br.readLine();
  //while (isDefined("line")) {
   //writeoutput(line);
  //}
  br.close();
  i.close();
</cfscript>

<cfdump var="#line#">

输出:

Linux

如果我发出类似的命令

ls

我得到例如多行输出

README.TXT

改为:

README.TXT VERSION.txt _-Railo-Getting-Started-_.html bin etc jre lib license-eplv10-aslv20.html modules notice.html resources start start.d start.ini start.jar stop webapps

【问题讨论】:

  • 什么是“内存错误”?添加你得到的真正错误以及你得到它的确切位置。现在你的代码在逻辑上只读取一行,它只会接收一行。
  • 我收到了java.lang.OutOfMemoryError: Java heap space。我知道我的代码只读取一行,知道如何全部读取吗?
  • 有理由不只使用 cfexecute 吗?我知道 cfexecute 没有提供给您的几个功能(工作目录、环境变量和作为输入流的结果),但您的代码示例似乎没有显示需要这些功能。如果您只想在收集后使用整个输出字符串,那么运行 cfexecute 会更容易。

标签: java coldfusion railo


【解决方案1】:

发现问题,我需要在循环中再次添加line = br.readLine();。工作代码:

<cfscript>
  str = ":>exec ls -al";
  exec_init=str.split(":>exec ");
  exec=exec_init[2].split(" ");
  p = createObject("java","java.lang.ProcessBuilder").init(exec).start();
  i = createObject("java","java.io.InputStreamReader").init(p.getInputStream());
  br = createObject("java","java.io.BufferedReader").init(i);
  line = br.readLine();
  while (isDefined("line")) {
   writeoutput(line);
   line = br.readLine();
  }
  br.close();
  i.close();
</cfscript>

【讨论】:

  • (编辑)不要忘记处理错误流以及输出。如果需要,您可以使用 redirectErrorStream(true) 将错误流重定向到标准输出
  • 感谢您的提示!知道怎么做吗?
  • 要么单独读取getErrorStream(),就像使用 p.getInputStream() 一样,要么使用ProcessBuilder.redirectErrorStream(true),以便将错误写入标准流。对于后者,您必须将 init()start() 调用分成两行,以便您可以访问 ProcessBuilder 对象。此外,如果您想等待进程完成,请使用 p.waitFor() 并检查 exitValue 以获得最终状态。如果 0,那么你知道发生了错误。
  • 谢谢!我感谢您的帮助!我会这样做的。
猜你喜欢
  • 2016-05-06
  • 1970-01-01
  • 2015-02-13
  • 2023-03-18
  • 2018-10-06
  • 1970-01-01
  • 2011-08-03
  • 2015-08-18
  • 1970-01-01
相关资源
最近更新 更多