2009-12-12 86 views
-1

我有一個.sh文件,我在類中創建一個war文件,位於web-inf/classes/test/test.class中。我正在從測試訪問.sh文件使用以下語法 字符串CMD =「./ test.sh」 運行時API目錄結構來訪問戰爭中的.sh文件

類我不能夠訪問此文件,如果我把它。我想知道我在哪裏可以放在WEB-INF/classes中下.s文件在war中訪問test.class的路徑爲./test.sh?

+2

我並不意味着粗魯,但實際上,您應該:1.花些時間來設置問題的格式,使用適當的大小寫和標點符號2.不要在X時間發佈相同的問題(請參閱http://stackoverflow.com/問題/ 1893099/not-able-to-run-sh-file-using-java)3.學習如何提出「智能問題」4.閱讀FAQ。 – 2009-12-12 12:22:47

回答

1

根據其他問題您的意見,您使用下面的代碼來調用腳本:

Process p = Runtime.getRuntime().exec(cmd); 

如同在Javadoc解釋,這相當於exec(command, null, null)的行爲與調用與調用exec(cmdarray, envp, dir)完全相同。現在,如果我們看一下exec(String[] cmdarray, String[] envp, File dir) javadoc中,我們可以讀到:

新的子進程的工作目錄是由dir規定。如果dirnull,子進程繼承當前進程的當前工作目錄。

換句話說,你的情況,你的腳本test.sh預計將位於應用服務器的工作目錄,即從java命令調用該文件系統中的位置(這是當然不是WEB-INF/classes)。該目錄被設置在user.dir系統屬性,你可以閱讀如下:

String cwd = System.getProperty("user.dir") 

另外請注意,您不能change the working directory。實際上,理論上你應該編寫代碼,以便它不依賴於當前工作目錄的可移植性(即使在你的情況下這並不重要,因爲使用Runtime API會讓代碼不能真正移植)。

總之,你有幾種選擇(他們都不是我說的真的很容易攜帶,但最後一個是「少雪上加霜」):

  • hello.sh腳本的應用程序服務器的工作目錄。
  • 把它放在其他地方,並指向它相對於工作目錄(./path/to/hello.sh)。
  • 把它放在別的地方,用絕對路徑指向它(/path/to/hello.sh)。
  • 將它放在其他地方,並在調用exec()時使用dir參數。
  • 將它放在WAR中,並使用getResourceAsStream()讀取它,將其寫入tmp目錄,使其可執行,並按照Brian的建議將其寫入exec()

在我看來,最後一個選項是(只)的路要走,可以這樣實現(假設腳本是在同一個包類,即WEB-INF/classes/test/hello.sh):

InputStream is = this.getClass().getResourceAsStream("hello.sh"); 

String[] cmd = null; 
File tempFile = null; 

tempFile = File.createTempFile("hello", "sh"); 
// extract the embedded hello.sh file from the war and save it to above file 
OutputStream os = new FileOutputStream(tempFile); 
byte[] buffer = new byte[1024]; 
int bytes; 
while((bytes = is.read(buffer)) != -1) { 
    os.write(buffer, 0, bytes); 
} 
os.close();  

tempFile.setExecutable(true); 

cmd = new String[] { tempFile.getAbsolutePath() }; 

Runtime runtime = Runtime.getRuntime(); 
Process process = runtime.exec(cmd); 
+0

如何使sh文件在java代碼中可執行? tempFile.setExecutable(true);不起作用 – sarah 2009-12-14 04:57:17

+0

這很奇怪,我不知道任何其他方式。文件的權限是什麼? – 2009-12-16 11:35:04

+0

+1,用於描述戰爭類路徑 – Ceilingfish 2010-05-27 13:52:21

0

我會閱讀.sh通過ClassLoader.getResourceAsStream()

然後你有兩種選擇:

  1. 寫入到一個目錄(也許/tmp?),更改權限,然後從那裏執行它。
  2. (多一點參與)。通過Runtime.exec()執行/bin/bash,然後通過標準輸入管腳本。

您將無法從結構的.war執行腳本直接