views:

159

answers:

7

Would like to make anapplication in Java that will not automatically parse parameters used on the command-line. Currently, java requires public static void main(string[]) as the entry point signature. I would like just a single string that I parse myself. Can this be done at all?

Here's an example: java MyProgram Hello World

I would want it to give me Hello World without requiring quotes around that string. I would even settle for java giving me the entire java MyProgram Hello World. I'm thinking this is something beyond Java and has more to do with the shell.

+1  A: 

Java always requires this signature. You can build a single string from the parameters in your main-method, though.

See this for examples on how to do this.

middus
A: 

Quick and Dirty fix - just concatenate all the parameters that are passed in.

Christopherous 5000
Concatenating is not enough in his example, you'd need to spaces in between.
middus
It still won't be enough if you quoted some of the parameters.
dan04
A: 
StringBuilder b = new StringBuilder();
for (string s : commandLineArgs) {
    b.append(s);
    b.append(" ");
}

// do what you want with b
Taylor Leese
+6  A: 

You're correct about the shell part. Assuming you're on Unix, your Unix shell will split your input string on whitespace and then hand you back each piece as an element in the array that is input to "main". The only way to get everything in as a single string is to quote it like this (which you said you didn't want):

java MyProgram 'Hello World'

If you don't want to do that, the easiest thing to do is just recombine them into a string:

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder();
    for(String s : args) {
        sb.append(s);
        sb.append(" "); //some length of whitespace
    }

    String yourString = sb.toString().trim();
}

The real problem here is that if you try to avoid quoting and you recombine the input strings yourself, you're going to lose the amount of whitespace between each word. If you recombine, all of the following command lines:

java MyProgram Hello World
java MyProgram Hello    World
java MyProgram Hello                           World

will still just show up as "Hello World" inside your program.

Brent Nash
This loses the space characters.
middus
Yeah, saw that right after I post, thanks! Unfortunately there's no way to faithfully recreate the whitespace without quoting on the command line.
Brent Nash
On Windows the whole command line (at least the bit after the command?) is available to a process (`GetCommandLine`, IIRC), which it then parses with another OS call. On UNIX, the shell interprets the command line, so the process doesn't get to see it at all.
Tom Hawtin - tackline
@tackline Good to know...been awhile since I had to do this stuff on Windows.
Brent Nash
Also, on UNIX, the asterisk * will be expanded... no way to know whether all the files were specified or if an asterisk was given.
Michael Aaron Safyan
@Michael Yeah, good point. You'd be vulnerable to all special Unix characters such as * or ? (or you could even get pathological about if people put something like $PATH and you didn't want it expanded).
Brent Nash
+1  A: 

Just join the strings:

class MyProgram {
    public static void main(String [] args ) {
        String commandLine = join( args );
        System.out.println(commandLine);
        // go on 
     }
     private static String join( String [] args ) {
         StringBuilder builder = new StringBuilder();
         for( String arg : args ) {
             builder.append( arg );
             builder.append( ' ' );
         } 
         builder.delete( builder.length()-1, builder.length());
         return builder.toString();
      }
}

Output:

output

OscarRyz
A: 

No. It's not java that's parsing the command line but the shell. In order to prevent it you must quote the input.

java MyProgram "Hello World"
Chris Nava
+1  A: 

This is more of a hack than anything and is tackling the problem from the other side of things but there is a variable in bash called IFS or internal field separator which tells the shell what to consider a delimiter. If one were to wrap up a read with a change in IFS you could gain the same basic effect you are going for albeit with the tedium of needing to put in the data manually every time.

Just a suggestion, bash below.

#!/bin/bash

IFS="
"

read TMP

java $1 \"$TMP\"

unset IFS
Mimisbrunnr