我有一个java应用程序。我使用 Runtime.getRuntime().exec 来调用批处理文件。当我使用 Runtime.getRuntime().exec 调用 Linux 批处理文件时,批处理文件找不到自己的目录。我在批处理文件中使用 pwd 命令,但它返回应用程序路径。我需要批处理文件本身的物理路径。我怎样才能做到这一点?
我正在使用 ProcessBuilder 运行 Windows 可执行文件...我需要运行的确切命令是:
"C:\Program Files\CCBU\CCBU.exe" -d"C:\My Data\projects\ccbu\ciccb-report.xls" -tf"C:\Program Files\CCBU\loss-billing-filters.txt"
Run Code Online (Sandbox Code Playgroud)
如果我从命令提示符运行上述命令,它工作正常。
如果我随后将命令和参数发出为 String [] 数组,如以下 StackOverflow 帖子(ProcessBuilder 在命令行中添加额外的引号)所示,则会失败,因为目录路径中的空格以某种方式破坏了 CCBU.exe 可执行文件的参数:
[log-snippet]
2015-08-31 10:39:08,937 [main] INFO rpd.primary - C:\Program Files\CCBU\CCBU.exe
logging to the given report's directory
Configuration file is: ./CCBUConfigFile.txt
Running with the following settings:
Report Filepath: C:\My
Search Terms FilePath: C:\Program
2015-08-31 10:39:08,948 [main] INFO rpd.primary - STDERR:--------------------
2015-08-31 10:39:08,961 [main] INFO rpd.primary -
Warning: parameter Data\projects\ccbu\ciccb-report.xls not recognized. Ignoring
Warning: parameter Files\CCBU\loss-billing-filters.txt not recognized. Ignoring
Error: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 ProcessBuilder 加载二进制文件,将其保持在加载状态,然后偶尔放入数据并解析输出。
我现在所拥有的抛出一个异常,表示流已关闭。
Process我对 Java 的工作原理有误解吗?我尝试在此处运行的二进制文件接受来自标准输入的输入并将结果打印到标准输出。它应该有效。如果我通过 cmd 手动输入二进制文件,则该行为是预期的,但我想知道为什么在 Java 中调用时这不起作用。
我的代码如下所示:
public class Run {
public static void main(String [] args) throws IOException, InterruptedException{
List<String> cmd = new ArrayList<String>();
cmd.add("/path/to/binary");
cmd.add("/path/to/param.par");
Process process=null;
try {
process = new ProcessBuilder().inheritIO().command(cmd).start();
} catch (IOException e) {
e.printStackTrace();
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
writer.write("Hi\\nhow\\nare\\you\\n?\\n\\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
String l=null;
while((l=reader.readLine())!=null){
System.out.println(l);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的例外是这样的:读取参数文件...java.io.IOException:流在 java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:433) …
我尝试从 Java 程序切换Runtime.exec(command)到ProcessBuilder执行 ImageMagick 。convert转换的选项是从用户作为字符串传入的,因此我无法轻松地分离参数以将它们单独传递给 的ProcessBuilder构造函数。在(Unix)命令行上运行的实际命令是
convert -colorspace gray -enhance -density 300 in.pdf out.pdf
Run Code Online (Sandbox Code Playgroud)
我怎样才能让它工作:
public class Demo {
public static void main(String[] args) throws IOException, InterruptedException {
String convertOptions = "-colorspace gray -enhance -density 300"; // arguments passed in at runtime
ProcessBuilder bp = new ProcessBuilder(new String []{"convert",convertOptions,"in.pdf","out.pdf"});
Process process = bp.start();
process.waitFor();
}
}
Run Code Online (Sandbox Code Playgroud)
目前,代码只是运行
我正在尝试模拟 ProcessBuilder 的构造函数。问题是当调用构造函数时它返回 null。
班级代码:
public static void enable() throws IOException, InterruptedException {
logger.info("Enable NTP server...");
String ntpAddress = AppConfig.getInstance().getString(AppConfig.NTP_SERVER, "");
AppConfig.getInstance().getBoolean(AppConfig.NTP_ENABLED, true);
String enableNtp = "chkconfig ntpd on " + SEPARATOR + " service ntpd stop " + SEPARATOR + " ntpdate " + ntpAddress + " " + SEPARATOR + " service ntpd start";
String[] commandArr = {"bash", "-c", enableNtp};
ProcessBuilder pb = new ProcessBuilder(commandArr);
pb.redirectErrorStream(true);
Process proc = pb.start();
try (BufferedReader in = new BufferedReader(new InputStreamReader(
proc.getInputStream()))) …Run Code Online (Sandbox Code Playgroud) 我需要在低优先级下启动CPU密集型系统进程,这样它不会减慢我的服务器速度.我怎么能在Linux上这样做?
这与此问题类似:使用Runtime.exec/ProcessBuilder.start以低优先级启动Java进程?除了Linux而不是Windows.如果在进程启动后更改进程的优先级(只要没有太多延迟),则可以.
我创建了一个可执行jar并使用另一个java程序的process builder执行它.这是我的代码 -
public class SomeClass {
public static void main(String[] args) {
Process p = null;
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "src.jar");
pb.directory(new File("/Users/vivek/servers/azkaban-0.10/TestApp/src"));
try {
p = pb.start();
} catch(Exception ex) {
ex.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
}
我正在尝试从eclipse调试src.jar.我在调试配置中将项目src作为外部项目提供,但它仍然没有达到我的任何断点.有没有办法为这样的东西设置调试环境?
我正在java中编写测试程序来测试我与django中的restfull api的连接(精确地说是djangorestframework).其中一个选择是用卷曲测试api.从shell运行curl命令它工作正常:例如:
curl --show-error --request GET --header 'Accept: application/json' --user "user:pwd" http://127.0.0.1:8000/api/v1/
Run Code Online (Sandbox Code Playgroud)
这很好地返回了json格式的api根URL和helptext.
现在,当我尝试使用ProcessBuilder从java调用相同的内容时,我得到了这样的答案:
{"detail": "You do not have permission to access this resource. You may need to login or otherwise authenticate the request."}
Run Code Online (Sandbox Code Playgroud)
我使用的java代码是:
ProcessBuilder p=new ProcessBuilder("curl","--show-error", "--request","GET",
"--header","'Accept: application/json'", "--user","\"" + userName + ":" + password + "\"", getApiRootUrlString());
final Process shell = p.start();
Run Code Online (Sandbox Code Playgroud)
因为我也通过以下方式捕获错误流:
InputStream errorStream= shell.getErrorStream();
InputStream shellIn = shell.getInputStream();
Run Code Online (Sandbox Code Playgroud)
我知道他启动了curl命令,因为在其中一个选项中出错会显示curl帮助文本.
我不确定调用它之间的区别是什么,非常确定它是相同的命令.
顺便说一句,'getApiRootUrlString()'返回正确的url: http://127.0.0.1:8000/api/v1/
关于JavaFX的新手问题我无法回答,尽管知道它必须非常简单,并且在我看过的任何地方都找不到任何资源(教程,许多Oracle在线文档,文章,以及已知的JavaFX博主等)
我正在开发一个运行应用程序的命令行(脚本),我已经成功地从脚本中获取输出(通过ProcessBuilder),我可以持续显示,就像在命令行上发生的那样.也就是说,我可以System.out.println(line);整天做,在控制台中显示输出,它只是返回正在运行的'myProcess'返回的输入流的输出,如下所示:
BufferedReader bri = new BufferedReader(new InputStreamReader(myProcess.getInputStream()))
Run Code Online (Sandbox Code Playgroud)
所以我能够看到从脚本返回的所有输出.
我想设置一个JavaFX TextArea或ScrollPane,或者不确定是什么,以显示这个输出文本(它有很多,如几千行)作为脚本中正在发生的'进展',当它发生的时候.我有一个场景,我有按钮并从这个场景获取输入以启动脚本运行,但现在我想显示点击"运行此脚本"按钮的结果,可以这么说.
我假设我需要创建一个TextArea,如此处所述,或者TextBuilder可能对开始制作它很有用.不确定.
我需要一些帮助来设置绑定或自动滚动/自动更新的一部分.
有人可以为我提供一个开始的地方,用JavaFX做到这一点吗?我宁愿不使用Swing.
(我正在使用JavaFX 2.2,JDK 1.7u7,所有最新的东西,是的,这是一个FXML应用程序 - 所以这样做是首选.)
更新:Sergey Grinev的回答在绑定部分非常有帮助.但是,当我要求"如何设置一些帮助"时,这里有一些更详细的信息 - 基本上,我需要将控制权返回到主场景以允许用户取消脚本,或者以其他方式监视这是怎么回事.所以我想"生成"运行该脚本的进程(也就是说,有某种'自由运行进程'),但仍然从中获取输出.(在我最初的问题中,我对此并不十分清楚.)
我在这里使用的技术(见下文)是在进程上执行waitFor,但这当然意味着在脚本执行时对话框/场景被"挂起".我想获得控制权,但是如何将'p'(进程)传递给其他控制器部分(或者,只需启动其他进程传入参数以启动脚本并让它启动脚本)然后通过绑定Sergey Grinev提到自动更新 - 没有"挂"场景/窗口?另外:如果用户请求,我可以"停止"这个其他过程吗?
这是我当前的代码('等待'而脚本 - 运行需要20-40分钟! - 完成;这不是我想要的,我想控制返回给用户):
public class MyController implements Initializable {
@FXML
private void handleRunScript(ActionEvent event) throws IOException {
ProcessBuilder pb = new ProcessBuilder("myscript.sh", "arg1", "arg2", ...);
Process p = pb.start();
try {
BufferedReader bri = new BufferedReader
(new InputStreamReader(p.getInputStream()));
String line;
while ((line = …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
ProcessBuilder pb = new ProcessBuilder( "java", "-jar", "test.jar", Integer.toString( jobId ), Integer.toString( software ), Integer.toString( entryPoint ), application );
pb.directory( new File("/home/userName/TestBSC") );
Process proc = pb.start();
Run Code Online (Sandbox Code Playgroud)
使用此命令从终端运行jar文件时:
java -jar test.jar 135 3 3 appName
然后它就像一个魅力.jar会在我的数据库中推送一些内容,所以我发现它正在运行.但是当我使用上面提到的processBuilder代码从我的JavaServlet中执行它时,我没有在我的数据库中获得任何数据,也没有任何错误.
但是进程本身正在运行,我在终端中用"ps ax"检查了它.所以我想知道这里的区别在哪里?我究竟做错了什么?
有人有想法吗?
编辑:更多代码:
ProcessBuilder pb = new ProcessBuilder( "java", "-jar", "test.jar", Integer.toString( jobId ), Integer.toString( software ), Integer.toString( entryPoint ), application );
pb.directory( new File("/home/userName/TestBSC") );
Process proc = pb.start();
System.out.println( "Job running" );
proc.waitFor(); // wait until jar is finished …Run Code Online (Sandbox Code Playgroud) processbuilder ×10
java ×9
bash ×1
curl ×1
fxml ×1
jar ×1
javafx ×1
javafx-2 ×1
json ×1
junit ×1
linux ×1
powermockito ×1
process ×1
pwd ×1
runtime.exec ×1
scheduling ×1
windows ×1