2012-01-09 56 views
11

我在尋找到一個最有效的方式來決定:Java,Runtime.exe或ProcessBuilder:如何知道文件是shell還是binary?

  • 我應該preprend與外殼可執行
  • 如果是用戶提供的命令行,將在該可執行文件是什麼呢? (/ bin/sh?/ usr/bin/perl?/ usr/bin/ksh?c:/../ cmd.exe?)

已知要從Java啓動shell腳本應該啓動所述殼來代替:

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "script.sh", "arg1", "arg2); 

要啓動一個二進制應該開始二進制本身:如果二進制與殼執行

ProcessBuilder pb = new ProcessBuilder("/path/binary", "arg1", "arg2); 

,它產生一個錯誤:

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2); 
(sh: cannot execute binary file) 

如果一個shell腳本沒有外殼的二進制執行,它會產生一個錯誤:

ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2); 
(error 2: file not found) 

我的情況是在我的應用程序不知道是什麼開始,二進制或腳本。

已啓動的應用程序是由最終用戶提供的事件處理程序。它很可能是在Unix下執行的shell腳本;但它可以是Windows下的* .cmd,或者是在某個不太明確的平臺下執行的Perl腳本。畢竟它是Java。

我第一次天真的嘗試是用shell啓動命令行,看看它是否有效。如果不是,請嘗試將其作爲二進制文件執行。

這是醜陋而危險的:在平臺和shell的某些未知組合下,第二次運行可能仍會執行第二次腳本,結果不可預知。

另外,我無法分辨何時腳本開始正常,並且由於某些問題而導致它無法啓動,當我無法啓動它時。

現在我考慮的最好的事情是:

  • 讀了劇本,並尋找任何不可打印的字節
  • 如果找到了,認爲這是一個二進制
  • 如果沒有,添加/箱/ sh(或cmd.exe如果在Windows下)

請告知,如果你有任何更好的想法。

UPDATE /部分解決

謝謝大家誰與我分享他們的想法。

事實證明,我都弄得自己和

預先設置應在用戶輸入的命令行之前提供二進制不要求上網:)其餘:

  1. 腳本在PATH
  2. (對於Unix)的腳本是可執行的
  3. (對於Unix)的腳本有#!/路徑/到/解釋

當我測試我的代碼時,這些條件中的一個或另一個沒有遇到。 :-(

後從臨時腳本已被執行認真執行測試。

點3只可以由用戶來完成,並已對用戶手冊中加以記錄。

由於這些腳本傳播到目標系統的方式,它們可能不可執行,並且可能不在PATH中。

我關心的唯一路徑是相對路徑,所以它足以將./添加到任何相對路徑。

Making th在Unix(以及任何其他平臺)下可執行的腳本是一個更大的挑戰。這不是WORA。將/ bin/sh放在它的前面可能會有所幫助,但如果我在Solaris下記住,shell不會執行不可執行的腳本。

本週晚些時候我會發布另一個更新。

+1

你的shell腳本是否在頂部有一個合適的shebang行('#!')?如果是這樣,那麼你可以簡單地讓內核運行它(只要它是'+ x'可執行文件),而不用擔心它可能需要哪個命令解釋器。 – 2012-01-09 05:25:32

+0

我不知道。該腳本來自最終用戶,不隨軟件提供。 – 2012-01-09 05:26:55

回答

2

一種可能的解決方案是生成一個腳本,該腳本將程序中的執行腳本/二進制文件封裝起來。這樣你就知道它總是一個腳本。生成的腳本只執行內部腳本/二進制文件並返回錯誤代碼(並可能重定向輸入/輸出)。完成後,您可以簡單地刪除它。 Java允許您非常輕鬆地創建臨時文件。

3

它應該是一個紅旗,你必須跳過這些箍來運行命令。首先是因爲這變得非常複雜,其次是因爲Java被設計爲獨立於平臺。當你正在研究操作系統特定的黑客讓內置類工作時,你應該退後一步並重新檢查你的假設。

ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2); 
(error 2: file not found) 

注意,錯誤消息「找不到文件」,而不是「不能執行shell腳本」或類似的錯誤。導致此錯誤的最可能原因不是您正在執行腳本,而是腳本無法找到。

如果腳本在當前目錄中,則需要在前面添加一個./。如果您沒有爲可執行文件指定明確的路徑,那麼可執行文件必須駐留在您的環境變量$PATH中的一個目錄中。當前目錄.通常是而不是默認包含在$PATH中。

ProcessBuilder pb = new ProcessBuilder("./script.sh", "arg1", "arg2); 

如果腳本名稱爲用戶提供的價值,那麼我會徵收的用戶的要求 - 你可以添加./他們,但UNIX程序通常儘量避免太有幫助。如果他們忘記把./那麼這就是他們的問題!

+0

感謝您用力沖洗我的大腦。的確,./script至少可以部分幫助你。 – 2012-01-10 02:57:44

0

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2); (sh: cannot execute binary file)

的ProcessBuilder PB =新的ProcessBuilder( 「/ bin/sh的」, 「-c」, 「/路徑/二進制」, 「ARG1」,「ARG2); (SH:不能執行二進制文件)

一種選擇是接受來自用戶的解釋路徑作爲另一個參數(可能是從已知值的列表)。

(這可能是一個評論。我不能讓格式右)

相關問題