我试图从java代码运行shell脚本,但我遇到了问题。该脚本位于batchstart.sh文件中 -
#!/bin/ksh
export DISPLAY=:0.0
现在,脚本在命令行上以点运行 - 。 batchstart.sh
如何从java运行它?我的java代码如下。它抛出以下异常 -
java.io.IOException: .: not found at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.<init>(UNIXProcess.java:102) at java.lang.ProcessImpl.start(ProcessImpl.java:65) at java.lang.ProcessBuilder.start(ProcessBuilder.java:451) at java.lang.Runtime.exec(Runtime.java:591) at java.lang.Runtime.exec(Runtime.java:429) at SetDisplay.main(SetDisplay.java:12)
import java.io.*;
public class SetDisplay {
public static void main(String[] args) {
File wd = new File("/myhomedir/");
System.out.println("Working Directory: " +wd);
Process proc = null;
try {
proc = Runtime.getRuntime().exec(". batchstart.sh", null, wd);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如何运行shell脚本?
我也尝试了以下代码,但这也不起作用。
File wd = new File("/bin");
System.out.println(wd);
Process proc = null;
try {
proc = Runtime.getRuntime().exec("/bin/bash", null, wd);
}
catch (IOException e) {
e.printStackTrace();
}
if (proc != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
out.println("cd /home/");
out.println(". batchstart.sh");
out.println("exit");
try {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
proc.waitFor();
in.close();
out.close();
proc.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
}
答案 0 :(得分:1)
源命令(“.
”)是内置的shell。您必须显式运行/bin/ksh
,将脚本名称作为参数传递(后跟任何脚本参数)。
如果需要来源脚本,则会遇到更大的问题。这通常意味着环境变化发生在当前shell的上下文中,而不是子shell。
这不适用于Java,因为Java不是shell。您需要弄清楚如何使用Java更改环境。
当然,如果我错了,只有设置DISPLAY的脚本还有更多,它可能会按照建议工作。
您将要使用的方法取决于您要实现的目标(如“您是否正在使用依赖于DISPLAY设置的exec()运行其他程序?”或“您的Java程序是否需要”)显示设置?“)。
如果您在评论中说明,只有您的Java程序需要设置DISPLAY,只需在程序运行之前将其设置为外部。创建一个cmd(或bash)文件,设置DISPLAY变量然后调用JRE来运行程序。
#/bin/ksh
export DISPLAY-:0.0
/usr/bin/jre/java your_program blah.blah.blah
我还会修改你的main()
,检查它是否已设置为某些内容,如果不是,则优先退出:
if (System.getenv ("DISPLAY") == null)
// doesn't exist, exit gracefully.
答案 1 :(得分:0)
期间“。”是一个内置的shell,并且“就地”执行脚本,类似于C / C ++中的#include。使用“。”在shell脚本之外没有任何意义。
如果你想从Java 运行脚本,你必须执行脚本解释器(/ bin / ksh):
Runtime.getRuntime().exec("/bin/ksh batchstart.sh", ...)
但请注意,这在语义上并不等同,因为您将batchstart.sh作为子流程执行而不是采购它。
答案 2 :(得分:0)
从命令行运行时,在脚本开头使用一个点表示该脚本应该在当前环境中运行,而不是生成一个新的子shell并使用一个新的复制当前环境。这允许您导出环境变量的新值,以供稍后从同一交互式shell运行的命令使用。
显然,只有从实际shell运行batchstart.sh
脚本时,此方法才有效。 Java不知道这种机制是如何工作的,因此点对它没有任何意义。脚本无法修改调用它的Java进程的环境。
如果您的目标是为Java进程运行的其他命令更改DISPLAY环境变量的值,请考虑使用ProcessBuilder
类为子进程指定新环境。 Java不包含在其自己的环境中修改变量的内置方法。