Java代码无法使用创建的临时文件(执行shell脚本的进程没有输出响应)
我正在编写一个Java代码,该代码将创建一个shell命令并将其写入临时文件,然后使用process builder运行该文件Java代码无法使用创建的临时文件(执行shell脚本的进程没有输出响应),java,processbuilder,Java,Processbuilder,我正在编写一个Java代码,该代码将创建一个shell命令并将其写入临时文件,然后使用process builder运行该文件 File file = null; InputStream input = getClass().getResourceAsStream("/somecommand.sh"); try { file = File.createTempFile("tempcmdline", ".sh"); } catch (IOExceptio
File file = null;
InputStream input = getClass().getResourceAsStream("/somecommand.sh");
try {
file = File.createTempFile("tempcmdline", ".sh");
} catch (IOException e1) {
e1.printStackTrace();
}
OutputStream out;
try {
out = new FileOutputStream(file);
BufferedReader reader=new BufferedReader(new InputStreamReader(input));
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));
String line;
while((line = reader.readLine()) != null) {
writer.write(line);
}
} catch (IOException e1) {
e1.printStackTrace();
}
Process p;
try {
List<String> cmdList = new ArrayList<String>();
cmdList.add("/usr/bin/bash");
cmdList.add("tempcmdline.sh");
ProcessBuilder pb = new ProcessBuilder(cmdList);
pb.redirectErrorStream(true);
p = pb.start();
IOUtils.copy(p.getInputStream(), System.out);
p.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
if((line = reader.readLine()) != null) {
System.out.println("some display" + line);
} else {
System.out.println("some other display");
}
File文件=null;
InputStream输入=getClass().getResourceAsStream(“/somecommand.sh”);
试一试{
file=file.createTempFile(“tempcmdline”,“.sh”);
}捕获(IOE1异常){
e1.printStackTrace();
}
输出流输出;
试一试{
out=新文件输出流(文件);
BufferedReader reader=新的BufferedReader(新的InputStreamReader(输入));
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));
弦线;
而((line=reader.readLine())!=null){
作者:写(行);
}
}捕获(IOE1异常){
e1.printStackTrace();
}
过程p;
试一试{
List cmdList=new ArrayList();
添加(“/usr/bin/bash”);
添加(“tempcmdline.sh”);
ProcessBuilder pb=新的ProcessBuilder(cmdList);
pb.重定向错误流(真);
p=pb.start();
复制(p.getInputStream(),System.out);
p、 waitFor();
BufferedReader=新的BufferedReader(新的InputStreamReader(p.getInputStream());
弦线;
如果((line=reader.readLine())!=null){
System.out.println(“某些显示”+行);
}否则{
System.out.println(“其他一些显示”);
}
找不到tempcmdline.sh时出错。我尝试添加/tmp/tempcmdline,认为在UNIX上createTempFile使用的默认临时目录将是/tmp
请共享我们可以指定目录并在过程中使用的任何工作代码
[编辑]我尝试使用file.getAbsolutePath()获取absolutepath,并在进程中传递完整路径名。但是,这会给出空响应(当我使用InputStreamReader读取进程输出时),而当我在Unix上手动运行shell脚本时,它会给出一条正确的1行o/p消息
[编辑]我发现正在创建的临时文件\r导致了问题
[更新]以下是适用于我的更新代码:
File file = null;
InputStream input = getClass().getResourceAsStream("/someCommand.sh");
try {
file = File.createTempFile("tempcmdline", ".sh");
String tempShell = file.getAbsolutePath();
Files.copy(input, Paths.get(tempShell), REPLACE_EXISTING);
file.deleteOnExit(); //comment for testing to see how it is written
} catch (IOException e1) {
e1.printStackTrace();
}
Process p;
try {
String tempShellFile = file.getAbsolutePath();
List<String> cmdList = new ArrayList<String>();
cmdList.add("sh");
cmdList.add(tempShellFile);
cmdList.add(applicationName);
cmdList.add(serviceAccount);
ProcessBuilder pb = new ProcessBuilder(cmdList);
//pb.redirectErrorStream(true);
p = pb.start();
//IOUtils.copy(p.getInputStream(), System.out); //uncomment for testing
p.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
if((line = reader.readLine()) != null) {
System.out.println("some message");
} else {
System.out.println("some other message");
}
}catch (IOException e) {
e.printStackTrace();
}catch (InterruptedException e) {
e.printStackTrace();
}
File文件=null;
InputStream输入=getClass().getResourceAsStream(“/someCommand.sh”);
试一试{
file=file.createTempFile(“tempcmdline”,“.sh”);
字符串tempShell=file.getAbsolutePath();
文件.copy(输入,路径.get(tempShell),替换现有文件);
file.deleteOnExit();//用于测试的注释,以查看它是如何编写的
}捕获(IOE1异常){
e1.printStackTrace();
}
过程p;
试一试{
字符串tempShellFile=file.getAbsolutePath();
List cmdList=new ArrayList();
cmdList.添加(“sh”);
添加(tempShellFile);
cmdList.add(应用程序名称);
添加(serviceAccount);
ProcessBuilder pb=新的ProcessBuilder(cmdList);
//pb.重定向错误流(真);
p=pb.start();
//IOUtils.copy(p.getInputStream(),System.out);//取消对测试的注释
p、 waitFor();
BufferedReader=新的BufferedReader(新的InputStreamReader(p.getInputStream());
弦线;
如果((line=reader.readLine())!=null){
System.out.println(“某些消息”);
}否则{
System.out.println(“其他消息”);
}
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}
要共享的错误详细信息和学习:
1) 最初的问题是来自进程的响应导致并没有InputStream;
然后,实际的错误出现在进程中,说明找不到这样的文件(tempcmdline.sh)
2) 在理解临时文件名将不同之后,我获得了绝对路径并将其传递给进程。
下一个错误是没有响应,好像shell脚本是空的。初始代码中的上面的循环没有处理换行符,并且不正确。添加的新代码具有修复
下一个错误是无效字符“\r”,这是由于在Windows上创建的shell脚本文件造成的。我只是在Eclipse编辑器上清理了它,结果很好
3) 调试后,我删除了IOUtils.copy步骤,因为我希望通过Inputstream读取输出
希望对某人有所帮助。似乎您正在尝试写入一个名为“/tmp/tempcmdline234765876.sh”的临时文件,然后尝试运行“tempcmdline.sh”
添加System.out.println(文件);以查看实际的临时文件名。我尝试使用file.getAbsolutepath()并将其传递给porcessbuilder,但返回值为null。什么是null?文件、getAbsolutepath或pb.start()?请在此帮助我。shell脚本输出为空响应。我已修复该问题,其工作正常。请参阅我的编辑。“无法使用”不是问题描述。您尚未提供实际的异常或错误消息。您尚未关闭输出文件。您正在丢失行终止符。您正在等待进程退出在您读取任何可能导致死锁的输出之前。您应该将其输出读取到流的末尾,然后等待。@user207421谢谢。我已经解决了这个问题。我将通过此练习编辑更新的代码和我的学习。您能检查更新的代码并共享您的输入吗?特别是关于死锁的输入。