[英]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.