Скопируйте файл с помощью `.jar` в WSL Ubuntu 16.04 - PullRequest
0 голосов
/ 02 апреля 2019

При попытке скопировать файл, который я создаю в сценарии .jar, который я запускаю в Windows Subsystems для Linux (WSL) Ubuntu 16.04, я получаю следующую ошибку:

Плохое выполнение: cp: not stat '"/ mnt / e / 18-09-19': такого файла или каталога нет

Неправильное выполнение: cp: невозможно указать 'Document': такого файла или каталога нет

Плохое выполнение: cp: не может определить 'что-то / что-то / SomeThing / PublicCodeLibrary / Java / mweCopy0 / vars "': такого файла или каталога нет

Или, если команда выполняется без кавычек в исходном пути:

Неправильное выполнение: cp: невозможно открыть '/ mnt / e / 18-09-19' для чтения: разрешение отклонено

Неправильное выполнение: cp: невозможно указать 'Document': такого файла или каталога нет

Плохое выполнение: cp: не может определить что-то / что-то / 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;
    }
}

Вопрос:

Как мне скопировать файл в WSL Ubuntu 16.04 из файла .jar?

Дополнительные попытки:

Мне известно, что существует разница в том, как терминал обрабатывает команды, когда пользователь печатает, и когда вы выполняете команды, например, из файла .jar, подобного этому. В частности, некоторый синтаксис не будет работать, так как вам необходимо передать, например, вывод команды на вход, или наоборот, команда cd также работает по-другому. Однако я пока не смог определить, почему команда cp будет затронута этими двумя явлениями, поскольку для этой команды нет выходных данных, относящихся к ее работе, и единственное относительное окружение - это среда Unix.

Обновление на основе комментариев: * Действительно, явные кавычки сделали путь недействительным. Кроме того, в конце пути выходной файл не должен содержаться, поэтому vars в конце command[8]=... удаляется. Однако, поскольку исходный путь может содержать пробелы в первых 8 символах, в настоящее время я изучаю, как включить пробелы в команду без добавления дополнительных явных кавычек.

1 Ответ

0 голосов
/ 03 апреля 2019

Решение:

Решение было найдено путем разделения команды и аргументов в каждой отдельной строке и передачи массива разделенных строк в Runtime.getRuntime (). Exec (команда), как предлагается в комментариях.

Примечания:

  1. Независимо от того, содержат ли аргументы пробелы или нет, ir имеет значение.
  2. Независимо от того, содержат ли аргументы пробелы или нет, аргументы должны не заключаться в кавычки.

Реализация:

Реализация была найдена с использованием двух дополнительных классов.Для этого приложения я просто добавил два класса в папку проекта src (там же, где находится основной класс).Дополнительные классы runCommandsWithArgs.java и SyncPipe.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_;
}
...