2011-06-24 103 views
-1

我存储在某些Linux系统.sh文件。该文件的完整路径是:Java代码来执行sh文件

/comviva/CPP/Kokila/TransactionHandler/scripts/stopTH.sh 

我特林通过

Runtime.getRuntime().exec(`/comviva/CPP/Kokila/TransactionHandler/scripts/stopTH.sh`) 

执行它,但它抛出一些异常。

我想从在MS-Windows环境下我的Java程序中执行该文件;可能吗?

+6

这是不可能在Windows本地运行在Unix shell脚本,这是你想要什么做 - 你需要将Unix shell脚本转换(不只是重命名)到Windows批处理文件(带有.bat或.cmd文件扩展名/后缀)。抛出哪个异常?您使用的是哪个版本的Java? – 2011-06-24 06:04:18

+2

您提到** ** Linux系统**和** Windows系统。 shell脚本位于你的Linux系统上,对吗?而您的Java应用程序(应该启动shell脚本)位于Windows系统上。那是对的吗? –

+4

什么是“一些例外”。这是一个重要的信息! – dmeister

回答

2

这是我的代码。正如评论所说,在Linux上工作,在Windows(XP)上失败。 AFAIK与Windows的问题是,cmd.exe是奇怪的关于它的参数。对于您的特定子任务,您可能可以通过使用引号进行操作并将子任务参数嵌入到子任务本身中。

/** Execute an abritrary shell command. 
    * returns the output as a String. 
    * Works on Linux, fails on Windows, 
    * not yet sure about OS X. 
    */ 
public static String ExecuteCommand(final String Cmd) { 
    boolean DB = false ; 
    if (DB) { 
     Debug.Log("*** Misc.ExecuteCommand() ***"); 
     Debug.Log("--- Cmd", Cmd); 
    } 
String Output = ""; 
String ELabel = ""; 
    String[] Command = new String[3]; 
    if (Misc.OSName().equals("WINDOWS")) { 
     Command[0] = System.getenv("ComSPec"); 
     Command[1] = "/C"; 
    } else { 
     Command[0] = "/bin/bash"; 
     Command[1] = "-c"; 
    } 
Command[2] = Cmd; 
    if (DB) { 
     Debug.Log("--- Command", Command); 
    } 
    if (Misc.OSName().equals("WINDOWS")) { 
     Debug.Log("This is WINDOWS; I give up"); 
     return ""; 
    } 
try { 
     ELabel = "new ProcessBuilder()"; 
     ProcessBuilder pb = new ProcessBuilder(Command); 
     ELabel = "redirectErrorStream()"; 
     pb.redirectErrorStream(true); 
     ELabel = "pb.start()"; 
     Process p = pb.start(); 
     ELabel = "p.getInputStream()"; 
     InputStream pout = p.getInputStream(); 
     ELabel = "p.waitFor()"; 
     int ExitCode = p.waitFor(); 
     int Avail; 
     while (true) { 
      ELabel = "pout.available()"; 
      if (pout.available() <= 0) { 
       break; 
      } 
      ELabel = "pout.read()"; 
      char inch = (char) pout.read(); 
      Output = Output + inch; 
     } 
     ELabel = "pout.close()"; 
     pout.close(); 
    } catch (Exception e) { 
     Debug.Log(ELabel, e); 
    } 

    if (DB) { 
     Debug.Log("--- Misc.ExecuteCommand() finished"); 
    } 
    return Output; 
} 

}

+5

对于Java中的方法和变量,您不应该有大写的第一个字符。 –

1

我做了一个快速测试在这里,下面的工作假设你有/斌/庆典你的机器上:

我/tmp/test.sh:

#!/bin/bash 
echo `ls` 

我的Java代码:

try { 
    InputStream is = Runtime.getRuntime().exec("/bin/bash /tmp/test.sh").getInputStream(); 
    int i = is.read(); 
    while(i > 0) { 
     System.out.print((char)i); 
     i = is.read(); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

输出:在当前目录下的所有文件

编辑:我有点被忽视,“从窗口中执行”的评论。我不知道你的意思。

3

要执行Windows上的.sh脚本,你必须安装合适的命令解释器。例如,您可以在您的Windows机器上安装Cygwin环境,并使用它的bash解释器。

但是,Windows甚至没有使用Cygwin Linux操作系统。有些脚本不会在没有改动的情况下从一个环境移植到另一个环境。如果我在Linux环境下通过Java执行脚本时遇到问题,我宁愿在该环境中调试该问题。

记住,你可以在调试模式下在Linux上启动Java程序和Windows中的IDE调试器附加到远程进程。

2

感谢大家的回复。我找到了解决问题的办法。对于这种情况,我们需要将我的Windows机器绑定到Linux系统。以下是有效的代码:

public String executeSHFile(String Username, String Password,String Hostname) 
    { 
     String hostname = Hostname; 
     String username = Username; 
     String password = Password; 
     try{ 
      Connection conn = new Connection(hostname); 
       conn.connect(); 
       boolean isAuthenticated = conn.authenticateWithPassword(username, password); 
       if (isAuthenticated == false) 
       throw new IOException("Authentication failed."); 
       Session sess = conn.openSession(); 
       sess.execCommand("sh //full path/file name.sh"); 

       System.out.println("Here is some information about the remote host:"); 
       InputStream stdout = new StreamGobbler(sess.getStdout()); 
       BufferedReader br = new BufferedReader(new InputStreamReader(stdout)); 
       while (true) 
       { 
        String line = br.readLine(); 
        if (line == null) 
         break; 
        current_time=line; 
        System.out.println(line); 
       } 

       System.out.println("ExitCode: " + sess.getExitStatus()); 
       /* Close this session */ 

       sess.close(); 

       /* Close the connection */ 

       conn.close(); 
     }catch(IOException e) 
     { 
      e.printStackTrace(System.err); 
      System.exit(2); 
     }finally{ 

     } 
} 

谢谢。

+1

您使用'Connection' /'Session'类:它们来自哪个库? –

0

你可以制作一个.bat文件(批处理文件),它可以在Windows上运行。 放在.bat文件中.SH文件的内容 从应用程序启动一个进程,如:

Process.Start("myFile.bat");