【发布时间】:2019-08-23 19:39:17
【问题描述】:
在尝试复制我在 Windows Subsystems for Linux (WSL) Ubuntu 16.04 中运行的 .jar 脚本中创建的文件时,我收到以下错误:
错误执行:cp: cannot stat '"/mnt/e/18-09-19': No such file or directory
执行错误:cp: cannot stat 'Document': No such file or directory
错误执行:cp: cannot stat 'something/something/SomeThing/PublicCodeLibrary/Java/mweCopy0/vars"': 没有这样的文件或目录
或者,如果在源路径中不带引号执行命令:
错误执行:cp:无法打开“/mnt/e/18-09-19”进行阅读:权限被拒绝
执行错误:cp: cannot stat 'Document': No such file or directory
错误执行:cp: cannot stat 'something/something/Something/PublicCodeLibrary/Java/mweCopy0/vars': No such file or directory
但是,为了验证它是否有效,我还将命令打印到终端,当我复制粘贴/手动执行它时,它确实有效,因为它更改了 /usr/share/taskd/pki/vars 文件内容。
所以我构建了一个最小的工作示例 (MWE),并使用以下命令运行脚本/MWE:java -jar mweCopy0.jar。
package mweCopy0;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.util.ArrayList;
public class mweCopy0 {
public static void main(String[] args) {
String vars = "vars";
char quotation = (char)34; // quotation mark "
String serverName = "exampleName";
//get the path of this file
String linuxPath = getJarLocation()[0];
// create the vars file
createVars(vars,serverName);
// execute commands
generateCommand(false,linuxPath,vars);
}
/**
* Generates the copying command and executes it.
* @param testRun
* @param linuxPath
* @param vars
*/
private static void generateCommand(boolean testRun,String linuxPath,String vars) {
//get commands
String[] commands = new String[24];
char quotation = (char)34; // quotation mark "
//commands[8] = "cp "+quotation+quotation+linuxPath+vars+quotation+" "+quotation+"/usr/share/taskd/pki/"+quotation+quotation;
//commands[8] = "cp "+quotation+linuxPath+vars+quotation+" "+quotation+"/usr/share/taskd/pki/"+quotation;
//commands[8] = "cp "+quotation+linuxPath+vars+quotation+" "+quotation+"/usr/share/taskd/pki"+quotation;
//commands[8] = quotation+"cp "+quotation+linuxPath+vars+quotation+" "+quotation+"/usr/share/taskd/pki"+quotation+quotation;
//commands[8] = "cp "+quotation+quotation+linuxPath+vars+quotation+" "+quotation+"/usr/share/taskd/pki"+quotation+quotation;
//commands[8] = "cp "+quotation+quotation+linuxPath+vars+" "+"/usr/share/taskd/pki"+quotation+quotation;
//commands[8] = "cp "+quotation+quotation+linuxPath+vars+" "+"~"+quotation+quotation;
//commands[8] = "cp "+quotation+linuxPath+vars+quotation+" "+"~";
//commands[8] = "cp "+quotation+linuxPath+vars+quotation+" "+quotation+"/usr/share/taskd/pki/vars"+quotation;
//commands[8] = "cp "+quotation+linuxPath+vars+quotation+" "+"/usr/share/taskd/pki/vars";
commands[8] = "cp "+quotation+linuxPath+vars+quotation+" "+"/usr/share/taskd/pki/";
runCommands(commands[8], false);
System.out.println("Ran:"+commands[8]);
}
/**
* This creates the Vars file required in command 8
* @param serverName
*/
private static void createVars(String fileName, String serverName) {
char quotation = (char)34; // quotation mark "
deleteFile(fileName);
PrintWriter writer;
try {
writer = new PrintWriter("vars", "UTF-8");
writer.println("BITS=4096");
writer.println("EXPIRATION_DAYS=365");
writer.println("ORGANIZATION="+quotation+"Göteborg Bit Factory"+quotation);
writer.println(serverName);
writer.println("COUNTRY=SE");
writer.println("STATE="+quotation+"Västra Götaland"+quotation);
writer.println("LOCALITY="+quotation+"Göteborg"+quotation);
writer.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Delete a file that is located in the same folder as the src folder of this project
* is located.
* @param fileName
*/
private static void deleteFile(String fileName) {
File file = new File(fileName);
try {
boolean result = Files.deleteIfExists(file.toPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //surround it in try catch block
}
/**
* This runs the command for the scenario where you are not prompted for yes.
* Source: https://github.com/AlvinFDK/FDK/blob/18d61bcc2121b13ae1b02345930f6f2264feb813/src/main/java/blackflames/alvin/bar/io/TerminalUnix.java
*/
public static ArrayList<ArrayList<String>> runCommands(String command,boolean ignoreOutput) {
String s = null;
String outputLines=null;
ArrayList<String> goodExecutionOutput=new ArrayList<String>();
ArrayList<String> errorExecutionOutput=new ArrayList<String>();
ArrayList<ArrayList<String>> returnLists = new ArrayList<ArrayList<String>>();
try {
// run the Unix "task nice0" command
Process p = Runtime.getRuntime().exec(command);
BufferedReader brGood = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader brError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// get output
if (!ignoreOutput) {
while ((s = brGood.readLine()) != null) {
//System.out.println("Adding:"+s);
goodExecutionOutput.add(s);
System.out.println("Good execution: "+s);
}
// get the error message
while ((s = brError.readLine()) != null) {
errorExecutionOutput.add(s);
System.out.println("Bad execution: "+s);
}
}
//System.exit(0);
}
catch (IOException e) {
System.out.println("Error: ");
e.printStackTrace();
System.exit(-1);
}
//Merge outputLists and return
returnLists.add(goodExecutionOutput);
returnLists.add(errorExecutionOutput);
return returnLists;
}
/**
* This gets the current location of the compiled.jar file
* @return
*/
public static String[] getJarLocation() {
String[] paths= new String[2];
// get path of location of compiled .jar file of this project in windows format
File f = new File(System.getProperty("java.class.path"));
File dir = f.getAbsoluteFile().getParentFile();
paths[0] = dir.toString()+"/";
return paths;
}
}
问题:
如何在 WSL Ubuntu 16.04 中从 .jar 文件中复制文件?
其他尝试:
我知道,当用户键入时,终端处理命令的方式与从 .jar 这样的文件执行命令时,终端处理命令的方式有所不同。具体来说,某些语法不起作用,因为您需要将命令的输出通过管道传输到输入,反之亦然,cd 命令的功能也不同。但是,我还不能确定为什么cp 命令会受到这两种现象的影响,因为没有与此命令功能相关的输出,唯一的相对环境是 Unix 环境。
基于 cmets 的更新:*
实际上,显式引号使路径无效。此外,在结束路径中,不应包含输出文件,因此删除了command[8]=... 末尾的vars。但是,由于源路径的前 8 个字符中可能包含空格,我目前正在研究如何在命令中包含空格而不添加额外的显式引号。
【问题讨论】:
-
请注意,它在抱怨
"/usr/share/taskd/pki/"带双引号 - 我确定不存在。尝试在命令行上以'"/usr/share/taskd/pki/"'运行它,你会遇到同样的问题。不要创建命令行,而是使用接受数组的Runtime.exec版本。或使用ProcessBuilder。 -
非常感谢您的回复,这确实是由于引号导致的无效路径,而且输出文件
vars不应包含在目标路径中。然而,我仍然面临的困难包括(潜在的)空格(带有)在我的源路径(前 8 个字符)中,而不添加/包括引号。我正在寻找解决方案。如果这不起作用,我将研究ProcessBuilder并将我的尝试包含在Runtime.getRuntime().exec(command)方法中。 -
在带有数组的版本中,您在第一个元素中传递命令名称,在下一个元素中传递第一个参数等。每个参数可能包含空格或特殊字符或其他任何内容。因为它不通过外壳,所以没关系。
标签: java copy ubuntu-16.04 executable-jar windows-subsystem-for-linux