无法从java运行ksh脚本:java.io.IOException:。:not found

时间:2009-02-09 19:17:24

标签: java unix shell

我试图从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(); 
  } 
}

3 个答案:

答案 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不包含在其自己的环境中修改变量的内置方法。