[英]complete CMD command not running from java
我正在使用psql在Postgres DB上通過Java運行以下查詢:
psql.exe -U <user> -w -h <host> -d <db_name> -a -f <file> 2> "<path_to_file>\psql.log"
最初,java程序確實創建了文件一段時間。 然后我遇到了另一個問題,它沒有覆蓋日志文件。 因此,每次通過Java創建此日志文件后,我都會使用file.delete()函數。
現在,由於某種原因,Java甚至沒有創建日志文件。 如果我在命令提示符下手動運行以上命令,它絕對可以正常運行,但不能通過Java代碼運行。 我可以在Java日志中看到該命令正在運行,但是即使刪除了file.delete()函數,它也不會創建日志文件
我對此進行了大量研究,但找不到任何解決方案。 任何幫助將不勝感激。
它的代碼很長..所以我會告訴你相關的部分。
我正在從線程調用函數。 該功能的代碼如下:
public static void SaveACopyfileToServer(int auditid,String filepath,String fname,String tb_name,String plpgsql_path) throws Exception
{
Map<String, String> env = System.getenv();
String plpgsql = "\""+plpgsql_path+"\" -U "+env.get("PG_USER")+" -w -h "+env.get("PG_HOST")+" -d "+env.get("PG_DB")+" -a -f "+"\""+filepath+"copy_"+tb_name+auditid+".sql\" 2> \"C:\\ER\\ETL\\logs\\psql.log\"";
System.out.println(plpgsql);
Process p = Runtime.getRuntime().exec(plpgsql);
p.getOutputStream().close();
p.waitFor();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
Calendar cal10 = Calendar.getInstance();
System.out.println("Data loaded for "+tb_name+auditid+" at "+sdf.format(cal10.getTime()));
}
在此之后,我要調用另一個函數,該函數是:
public static void extracterrorreason(String fname,int auditid,String sessionid,Connection con_pg) throws FileNotFoundException, IOException, InterruptedException{
File file = new File("C:\\ER\\ETL\\logs\\psql.log");
if(file.exists())
{
System.out.println("File present");
}
else
{
System.out.println(file+" not found");
}
if (file.length()!=0){
System.out.println("Log file being read is "+file);
BufferedReader br = new BufferedReader(new FileReader(file));
String line = br.readLine();
String out_err = line.substring(line.indexOf("ERROR"));
System.out.println(out_err);
System.out.println("Error while loading the file into Database for file "+fname);
String comment = "CopyToStage','"+out_err;
Utils.updateAuditDetailTable(auditid, sessionid, -1, comment, true, con_pg,"");
br.close();
//file.delete();
}
}
第一個函數用來創建psql.log文件,但是現在它甚至沒有創建它。 不知道問題出在哪里。 每次我運行代碼並從第二個函數運行時,我都會得到未找到日志文件的打印行。 重定向cmd命令的輸出之前的部分工作正常。
我也嘗試過流程構建器
我什至用Process Builder嘗試過
String plpgsql = "\""+plpgsql_path+"\" -U "+env.get("PG_USER")+" -w -h "+env.get("PG_HOST")+" -d "+env.get("PG_DB")+" -a -f "+"\""+filepath+"copy_"+tb_name+auditid+".sql\" 2> \"C:\\ER\\ETL\\psql_" +auditid +".log\"";
ProcessBuilder pb = new ProcessBuilder("cmd.exe",plpgsql);
Process p =pb.start();
p.getOutputStream().close();
p.waitFor();
我希望問題在於Runtime.getRuntime().exec(plpgsql)
將命令行錯誤地拆分為參數。 基本上, exec
不理解引用。 相反,它會在看到一個或多個空格的位置進行拆分...即使這些空格用引號引起來也是如此。
解決方案是使用exec(String[])
重載,並將每個單獨的參數作為單獨的字符串傳遞; 例如
.exec(new String[]{plpgsql_path,
"-U",
env.get("PG_USER"),
"-w,
"-h",
// etcetera
});
更新
我沒有注意到您也在使用>
輸出重定向1 。
這對exec
也不起作用。 ( 所有 Shell語法也一樣。)要獲得重定向,您需要使用ProcessBuilder
和其中一種redirect
方法。
另一種選擇是在外殼中運行命令。 以字符串形式傳遞命令,然后讓外殼處理引號處理,環境變量的替換,globbing,重定向...等。
例如(如果您在UNIX,Linux或MacOSX上運行):
.exec(new String[]{"/bin/sh", "-c", plpgsql});
對於Windows
.exec(new String[]{"cmd.exe", "/C", plpgsql});
注意Windows情況下的“ / C”選項!
1-它為您服務,不會在您的源代碼中對〜200個字符的行進行換行! 檢查一下Java編碼標准對源代碼行長度的說明...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.