2

I am trying to create a java program that takes some user-input variables and passes them to a perl script (it actually finds a certain string within the perl script and replaces it with the user-input variables). Here is the code:

    String sedMain = "sed -e ";
    String sedFirstLine = "'s/AAA/"+newFirstLine+"/' -e ";
    String sedNewCntr = "'s/BBB/"+newCntr+"/' -e ";
    String sedNewSpacing = "'s/SPACE/"+newSpacing+"/' -e ";
    String sedNewDmax = "'s/MAX/"+newDmax+"/'";
    String sedFile = " /filepath/myperlscript.pl >  /filepath/myNEWperlscript.pl";
    String sedCommand=sedMain+sedFirstLine+sedNewCntr+sedNewSpacing+sedNewDmax+sedFile;
    System.out.println("SED COMMAND: "+sedCommand);
    String testRun = "touch /filepath/hello.txt";
    Process runSedCommand;
    runSedCommand = Runtime.getRuntime().exec(sedCommand);

I am using an IDE, and when the sed command is printed to the console, it looks correct. I copied the sed command from the console and ran it from the terminal, and it worked. I wrote the string "testRun" to see if there was a problem with the Process in Java, and it created the file "hello.txt". For some reason though, my program is not creating the output perl file "myNEWperlscript.pl". I am very confused as to why this is not working. Can anyone help out?

Jeremy Fisher
  • 2,510
  • 7
  • 30
  • 59
  • exec() takes a String[] with the program name and paramaters as its elements, but you are concatenating everything together into a single String and so effectively loosing the arguments. – Chris Stratton Jul 02 '13 at 15:22
  • So should I just write one string containing all the elements? – Jeremy Fisher Jul 02 '13 at 15:24
  • No, you need to create an array of Strings – Chris Stratton Jul 02 '13 at 15:25
  • Just out of curiosity, howcome when I executed the "testRun" string instead of the "sedCommand" string, it worked? testRun isn't a string array. – Jeremy Fisher Jul 02 '13 at 15:27
  • There's also a version of exec() which takes a command string with no arguments, though how touch got an argument is a bit of a mystery. Incidentally, your shell redirection of the output probably is not going to work, as you aren't invoking a shell. – Chris Stratton Jul 02 '13 at 15:29

2 Answers2

3

exec() takes a String[] with the program name and paramaters as its elements, but you are concatenating everything together into a single String and so effectively loosing the arguments.

Try something like this:

String[] cmd = {"sed", "first argument", "second argument"};
Runtime.getRuntime().exec(cmd);
Chris Stratton
  • 39,853
  • 6
  • 84
  • 117
2

use the

exec(String[] cmdarray) 

signature. the command is sed, -e is a parameter, 's/AAA/\n/' is another parameter and so on. So you will have

String[] command = new String[] {"sed", "-e", "s/AAA/\n/", "next parameter without single quotes", , "next parameter without quotes..."}
Runtime.getRuntime.exec(command);

This is the only way your parameters will get well formatted on it's way to the shell, otherwise weird sruff can happen as any quotes after the first token on the string will be considered to be just one parameter and so quotes can be escaped and things like that

David Hofmann
  • 5,683
  • 12
  • 50
  • 78
  • Actually, no shell is involved, unless the command executed is a shell. – Chris Stratton Jul 02 '13 at 15:47
  • Please clarify this, how then a child process is created from the JVM? – David Hofmann Jul 02 '13 at 15:50
  • 1
    By issuing a system call to the kernel. A shell is not necessary for that - a shell is just a program which gives you more convenience for launching programs, stringing their inputs and output pipes together, etc but ultimately uses a system call to the kernel just as you can. For example, the attempt to pipe the output of sed in this question depends on having a shell, but none is being invoked. So the poster will either need to capture the output of sed to a file, or launch a shell and tell that to launch sed and pipe the output to a file. – Chris Stratton Jul 02 '13 at 15:56
  • Thanks for the answer, so pipes and redirections can not be used when using exec in java ? – David Hofmann Jul 02 '13 at 15:58
  • 1
    Well, the shell syntax for creating them can't be used unless you exec a shell. That leaves the choices of doing yourself what a shell would do to set those up, or executing a shell and attempting to tell it what you want it to do on the command line, or executing a shell and piping commands into its stdin. – Chris Stratton Jul 02 '13 at 16:00
  • @ChrisStratton Wow it is unfortunate that the OP doesn't get notified by the comments on his answer. Otherwise we would have avoided [to ask a question on how to redirect the output from `exec`](http://stackoverflow.com/questions/17433309/sed-command-not-generating-output-file-when-called-in-java)... – user000001 Jul 02 '13 at 20:38