使用 Java 執行 cmd 命令時出現下一個錯誤。我在 Mac 筆記本電腦上作業。這是我的代碼:
private static String exportContainerFromImage(String container) {
//docker export mysql_dummy > ~/Documents/mysql_dummy.tar
String errorMessage = "";
String[] cmdArgs =
{"docker export mysql_dummy > ~/Documents/mysql_dummy.tar", "bash"};
Process process = Runtime.getRuntime().exec(cmdArgs);
}
但是我收到錯誤,error=2,沒有這樣的檔案或目錄,如果我直接在終端上執行命令它運行成功,我也嘗試將目錄更改為 ~\\Documents\\mysql_dummy.tar 并得到同樣的結果。
但是,如果我使用引數運行命令:
{"docker create -ti --name mysql_dummy mysql", "bash"};
它運行正常
有任何想法嗎?
uj5u.com熱心網友回復:
您將“shell 魔法”與“作業系統”混為一談。此外,您似乎對 cmdArgs 的陣列形式的作用感到非常困惑,因為您最后在其中標記了 bash。該陣列應該包含在 處的可執行檔案的完整路徑arr[0],以及處和 處的所有引數arr[1]。docker create -ti ...顯然不是檔案名,bash也顯然不是引數。
貝殼魔法?
如果您鍵入:
docker create -ti --name mysql_dummy mysql
在命令列上,bash(或 cmd.exe,如果在 Windows 上,或您使用的任何外殼)讀取它并執行一大堆替換魔法并對此進行決議。執行此操作的是外殼程式,而不是作業系統,并且 java 的 processbuilder 東西不是外殼程式,因此不會執行所有這些操作。你試圖做什么?運行整行,就好像它是一個可執行的單個檔案名,而它顯然不是。
這就是 shell 魔法——所有你不能用 exec 做的事情。幸運的是,java 是一種編程語言,因此您可以通過對它進行編程來完成所有這些事情。
- 通過在空格上拆分來決議引數。
- 參考以避免分裂,然后洗掉引號。
- 將其
~視為對 homedir 的參考。 - 替換
*和?在檔案名路徑中。 - 變數替換
- 使用
> somefile.txt或2> /dev/null或< file.in或諸如此類設定重定向。
你必須做這些事情。
另外,exec不能習慣這個,期間。像往常一樣,運行行程的唯一沒有問題的方法是始終使用ProcessBuilder,沒有例外。考慮runtime.exec一個你絕對不能呼叫的已知損壞的方法。
ProcessBuilder 允許您重定向輸出。
String[] cmdArgs = {
"/bin/docker" // note, FULL PATH!
"export",
"mysql_dummy"
};
File out = new File(System.getProperty("user.home"), "Documents/mysql_dummy.tar");
ProcessBuilder pb = new ProcessBuilder(cmdArgs);
pb.redirectOutput(new File(out));
pb.start();
這大概就是你想要的。
另一種方法是制作一個腳本(script.sh 或 script.bat),然后啟動 bash 或 cmd.exe 并要求它運行該腳本。
String[] args = { "/bin/bash", "-c", "/fully/qualified/path/to/the/script.sh" }
然后執行那個。現在,您可以隨心所欲地在該腳本中堆積*.txt、> foobar.txt、~/homediref和所有其他 shellism。
uj5u.com熱心網友回復:
總體而言,@rzwiterloot 的回答很好,但它遺漏了一些替代方案。
首先,我認為這個問題的最佳解決方案是:-o 選擇docker export.
"docker", "export", "mysql_dummy", "-o", "Documents/mysql_dummy.tar"
忽略~/這里,這組命令和引數將實作與... > Documents/mysql_dummy.tar重定向相同但不依賴于外殼的功能;docker export完全有能力處理該操作本身。
其次,如果你想從程式中運行一個 shell 命令,你可以。我不會推薦這個。但在某些情況下,這可能是有意義的。
另一種方法是制作一個腳本
您不必將命令放在單獨的檔案中。實際上,這是@rzwiterloot 的回答中的一個錯誤;-c允許您將命令傳遞給bash,而不是包含命令的檔案的路徑。
"bash", "-c", "docker export mysql_dummy > ~/Documents/mysql_dummy.tar"
但是,我建議您避免從您撰寫的任何程式中呼叫 shell。它們古怪而深奧,在這種情況下,幾乎總有一種更簡單的方法可以實作您想要的目標,例如docker export' -ooptiopn。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/372726.html
上一篇:結合cbq和cbimport命令的Couchbase腳本不起作用
下一篇:搜索并替換一個csv檔案
