繁体   English   中英

在WSL Ubuntu 16.04中使用`.jar`复制文件

[英]Copy file using `.jar` in WSL Ubuntu 16.04

在尝试复制我在Windows子系统Linux(WSL)Ubuntu 16.04中运行的.jar脚本中创建的文件时,收到以下错误:

执行不好:cp:不能统计'“/ mnt / e / 18-09-19':没有这样的文件或目录

执行不好:cp:无法统计'文档':没有这样的文件或目录

执行不好:cp:无法统计'something / something / SomeThing / PublicCodeLibrary / Java / mweCopy0 / vars“':没有这样的文件或目录

或者,如果在源路径中没有引号执行命令:

执行不好:cp:无法打开'/ mnt / e / 18-09-19'进行阅读:权限被拒绝

执行不好:cp:无法统计'文档':没有这样的文件或目录

执行不好:cp:不能统计'something / something / Something / PublicCodeLibrary / Java / mweCopy0 / vars':没有这样的文件或目录

但是,为了验证它的工作原理,我还将命令打印到终端,当我复制粘贴它/手动执行它时,它确实有效,因为它改变了/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;
    }
}

题:

如何从.jar文件中复制WSL Ubuntu 16.04中的文件?

额外尝试:

我知道终端在用户键入时如何处理命令,以及从例如像这样的.jar文件执行命令时有所不同。 具体来说,某些语法不起作用,因为您需要管道输出命令输出,反之亦然, cd命令的功能也不同。 但是,我还没有确定为什么cp命令会受到这两种现象的影响,因为没有与此命令相关的输出,并且唯一的相对环境是Unix环境。

基于注释更新:*实际上,显式引号使路径无效。 此外,在结束路径中,不应包含输出文件,因此将删除command[8]=...末尾的vars 但是,由于源路径可能包含前8个字符内的空格,因此我目前正在研究如何在命令中包含空格而不添加其他显式引号。

解:

通过在单独的字符串中分离命令和参数并将分离的字符串数组传递到注释中建议的Runtime.getRuntime()。exec(命令)中,找到了一个解决方案。

笔记:

  1. 无论是参数包含任何空格与否,是IR相关。
  2. 无论参数包含任何空格与否,论据应该用引号。

执行:

使用两个额外的类找到了一个实现。 对于这个应用程序,我刚刚在项目src文件夹中添加了两个类(与主类所在的文件夹相同)。 额外的类runCommandsWithArgs.javaSyncPipe.java列在主类(名为mweCopy0.java )下面。

mweCopy0.java

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 Main {

    /**
     * First the main gets the location for the file that it wants to copy somewhere.
     * Next it creates the file it wants to copy somewhere.
     * Then it generates the command to copy the file somewhere.
     * In method generateCommand, the command is passed through
     * to the module that actually executes the command in WSL Ubuntu 16.04.
     * 
     * You can quickly compile this script in Eclipse by:
     * Selecting Main.java in the Package Explorer,
     * press: alt+f>o>
     * Then select Java>Runnable JAR file>next
     * In launch configuration, select the Main.java
     * Select Package required libraries into generated JAR
     * press finish.
     * @param args
     */
    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 calls the class that executes it.
     * @param testRun
     * @param linuxPath
     * @param vars
     */
    private static void generateCommand(boolean testRun,String linuxPath,String vars) {
        String[] commands = new String[24];
        char quotation = (char)34; // quotation mark "

        // attempt 1: Original command 
        // cp /mnt/e/18-09-19 Document structure/personal/Programming/PublicCodeLibrary/Java/mweCopy0/vars /usr/share/taskd/pki/

        // separate the command from its arguments with a space between the arguments:
        // note it is irrelevant whether the arguments themselves contain spaces.
        String[] commandAndArgs = new String[3];
        commandAndArgs[0] = "cp";
        commandAndArgs[1] = "/mnt/e/18-09-19 Document structure/personal/Programming/PublicCodeLibrary/Java/mweCopy0/vars"; 
        commandAndArgs[2] = "/usr/share/taskd/pki/";

        RunCommandsWithArgs.runCommands(commandAndArgs);
        System.out.println("Ran:"+commandAndArgs);
    }

    /**
     * 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 Verification"+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 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;
    }
}

RunCommandsWithArgs.java

package mweCopy0;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

public class RunCommandsWithArgs {
    /**
     * This method actually executes the command in WSL Ubuntu 16.04 if you run the 
     * compiled .JAR file.
     * You can automatically answers yes to any input the command requires with the
     * stdin.println("yes"); line
     * @param command
     * @return
     */
    public static void runCommands(String[] commandPart) {
        Process p;

        try {
            p = Runtime.getRuntime().exec(commandPart);
            new Thread(new SyncPipe(p.getErrorStream(), System.err)).start();
            new Thread(new SyncPipe(p.getInputStream(), System.out)).start();
            PrintWriter stdin = new PrintWriter(p.getOutputStream());

            //This is not necessary but can be used to answer yes to being prompted
            //stdin.println("yes");

            // write any other commands you want here
            stdin.close();
            int returnCode = p.waitFor();
            System.out.println("Return code = " + returnCode);

        } catch (IOException | InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }       
    }
}

SyncPipe.java

package mweCopy0;

import java.io.InputStream;
import java.io.OutputStream;

class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
      istrm_ = istrm;
      ostrm_ = ostrm;
  }
  public void run() {
      try
      {
          final byte[] buffer = new byte[1024];
          for (int length = 0; (length = istrm_.read(buffer)) != -1; )
          {
              ostrm_.write(buffer, 0, length);
          }
      }
      catch (Exception e)
      {
          e.printStackTrace();
      }
  }
  private final OutputStream ostrm_;
  private final InputStream istrm_;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM