0

Am I not sending an array of commands, "hello world ", to exec() correctly?

correct output, hello world:

thufir@mordor:~$ 
thufir@mordor:~$ java -jar NetBeansProjects/HelloExec/dist/HelloExec.jar 
Apr 05, 2016 7:11:23 AM net.bounceme.mordor.telnet.Main run
INFO: starting..
Apr 05, 2016 7:11:23 AM net.bounceme.mordor.telnet.Telnet <init>
INFO: connecting..
Apr 05, 2016 7:11:23 AM net.bounceme.mordor.telnet.Telnet connect
INFO: connect..
Apr 05, 2016 7:11:23 AM net.bounceme.mordor.telnet.Telnet connect
INFO: [echo hello 1, echo hello 2, echo hello 3]
Apr 05, 2016 7:11:24 AM net.bounceme.mordor.telnet.Telnet connect
INFO: did process..
Apr 05, 2016 7:11:24 AM net.bounceme.mordor.telnet.Telnet connect
INFO: trying..
hello 1
Apr 05, 2016 7:11:24 AM net.bounceme.mordor.telnet.Telnet read
SEVERE: exiting.. 0
thufir@mordor:~$ 

code:

package net.bounceme.mordor.telnet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.lang.System.out;

public class Telnet {

    private final static Logger LOG = Logger.getLogger(Telnet.class.getName());

    public Telnet() {
        LOG.info("connecting..");
    }

    private List<String> getCommand() {
        List<String> commands = new ArrayList<>();
        commands.add("echo hello 1");
        commands.add("echo hello 2");
        commands.add("echo hello 3");
        return commands;
    }

    private void read(Process process) throws IOException, InterruptedException {
        BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        while ((line = input.readLine()) != null) {
            out.println(line);
        }
        int exitVal = process.waitFor();
        LOG.log(Level.SEVERE, "exiting.. {0}", exitVal);
    }

    private void connect() {
        LOG.info("connect..");
        Runtime runtime = Runtime.getRuntime();
        List<String> cmds = getCommand();
        String[] cmdArray = cmds.toArray(new String[cmds.size()]);
        String command = cmdArray[0];
        LOG.info(cmds.toString());
        Process process = null;
        try {
            process = runtime.exec(command);
        } catch (IOException ex) {
            LOG.severe("process wrong");
            Logger.getLogger(Telnet.class.getName()).log(Level.SEVERE, null, ex);
        }
        LOG.info("did process..");

        LOG.info("trying..");
        try {
            read(process);
        } catch (IOException | InterruptedException ex) {
            LOG.severe("read wrong");
            Logger.getLogger(Telnet.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void tryConnect() {
        connect();
    }
}

crash:

thufir@mordor:~$ 
thufir@mordor:~$ java -jar NetBeansProjects/HelloExec/dist/HelloExec.jar 
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Main run
INFO: starting..
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet <init>
INFO: connecting..
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet connect
INFO: connect..
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet connect
INFO: [echo hello 1, echo hello 2, echo hello 3]
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet connect
SEVERE: process wrong
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet connect
SEVERE: null
java.io.IOException: Cannot run program "echo hello 1": error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at java.lang.Runtime.exec(Runtime.java:485)
    at net.bounceme.mordor.telnet.Telnet.connect(Telnet.java:48)
    at net.bounceme.mordor.telnet.Telnet.tryConnect(Telnet.java:66)
    at net.bounceme.mordor.telnet.Main.run(Main.java:17)
    at net.bounceme.mordor.telnet.Main.main(Main.java:11)
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:248)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 6 more

Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet connect
INFO: did process..
Apr 05, 2016 7:12:32 AM net.bounceme.mordor.telnet.Telnet connect
INFO: trying..
Exception in thread "main" java.lang.NullPointerException
    at net.bounceme.mordor.telnet.Telnet.read(Telnet.java:30)
    at net.bounceme.mordor.telnet.Telnet.connect(Telnet.java:57)
    at net.bounceme.mordor.telnet.Telnet.tryConnect(Telnet.java:66)
    at net.bounceme.mordor.telnet.Main.run(Main.java:17)
    at net.bounceme.mordor.telnet.Main.main(Main.java:11)
thufir@mordor:~$ 

when trying to use cmdArray:

process = runtime.exec(cmdArray);

The reasoning:

...it's because when exec is given a single string, it parses it first (in a way that we don't like). In contrast, when exec is given a string array, it simply passes it on to the operating system without parsing it.

https://stackoverflow.com/a/19383655/262852

Community
  • 1
  • 1
Thufir
  • 8,216
  • 28
  • 125
  • 273
  • Try passing the command as array, i.e. `String[] cmd = {"echo", "hello", "1"}` and etc. – VolenD Apr 05 '16 at 21:08
  • do you mean "echo hello world 1", "echo hello world 2", etc **OR** do you mean "echo", "hello", "world"? – Thufir Apr 06 '16 at 09:26
  • I mean the second option - "echo", "hello", "world". Actually, "hello" and "world" are the argument, so it should be "echo", "hello world". This is actually the format in the answer which you have linked in your question. That's how the Linux [execve](http://linux.die.net/man/2/execve) call works as well. – VolenD Apr 06 '16 at 20:27

0 Answers0