Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

This may be a duplicate but the initial questions I have found the answer did not resolve the issue.

Yet another re-write of the question.

I have this Java application:

public static void main(final String[] args) {
    System.out.println("DEBUG: arguments passed to the main - " + Arrays.toString(args));
    System.exit(new TaskRunner().run(args));
}

If I call the code directly with two arguments:

$ nohup ${JAVA_HOME}/bin/java -cp /opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/* wib.runner.TaskRunner -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities" > /opt/sw/calypso/logs/taskrunner/log.direct.log 2>&1

it prints

[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities]

which is what I expect.  But if I write this shell script (startScheduledTask.sh):

NOW_DATE=`date '+%Y%m%d%H%M%S'`

nohup ${JAVA_HOME}/bin/java -cp some:classpath:values package.name.classname "$@"   > /opt/random/path/tplogs/classname/${aVariableLogName}.${NOW_DATE}.log 2>&1

and run it as

$ ./startScheduledTask.sh -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input -   Commodities Volatilities" &

I get this output:

[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD, IPV, -, EOD, Rates, Input, -, Commodities, Volatilities]

(i.e., the second argument gets broken up into nine arguments, because it contains eight spaces).  Therefore I believe that the script is at fault.

How do I fix this?

share|improve this question

closed as unclear what you're asking by Gilles, G-Man, Anthon, cuonglm, jimmij Aug 29 at 9:18

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

1  
Please clarify: how are you getting the lists of arguments that you show in the bottom half of your question, and what do you want to get?  Please do not respond in comments; edit your question to make it clearer. –  Scott Aug 28 at 5:31
    
Please review and let me know if this clears up the question. –  GvD Aug 28 at 5:39
    
The part you showed is correct, so the error is in one of the parts you didn't show. Probably in the way you invoke that script. Show us that part. –  Gilles Aug 28 at 23:08
    
Here's some quick advice: Withholding relevant information is bad, because it makes it impossible for us to figure out what's going on.  Bombarding us with irrelevant information is bad, because it makes it too hard for us to find the relevant information.  I realize that distinguishing between relevant information and irrelevant information can be hard, especially for somebody who is just learning.  But please try harder. –  Scott Aug 30 at 23:56
    
I edited your question again.  Of course, if you believe that I have misrepresented your situation or left out something important or critical, put it back.  But do not make statements about “JCommander” without telling us what it is and what it has to do with your question.  … … … … … … …  Why do your debug messages say DEBUG: : arguments when your debug code says DEBUG: arguments?  … … … … … … … …  P.S. I updated my answer; please see it. –  Scott Aug 31 at 3:17

1 Answer 1

up vote 2 down vote accepted

When the shell parses a command line, it removes quotes but remembers the text structure that they imply.  (That is a gross oversimplification; see bash(1) or Shell Command Language for more details.)  For example, the command-line input

-blah apple -secondfruit "green banana" -some more

causes the shell to identify six words, or tokens:

  1. -blah
  2. apple
  3. -secondfruit
  4. green banana
  5. -some
  6. more

which will be stored in memory as

-blahⓧappleⓧ-secondfruitⓧgreen bananaⓧ-someⓧmoreⓧ

where represents a null byte.  This will then sometimes be displayed or reported as

-blah apple -secondfruit green banana -some more

so you might believe that the quotes are just being ignored, and you have seven words, while, in fact, you have what you want.

Note:

In the above, represents a null byte.  What I'm describing here is standard shell argument-parsing processing.  If you type

ls -l fruit.sh "I came here for an argument" startScheduledTask.sh

the /bin/ls program gets invoked with the string

lsⓧ-lⓧfruit.shⓧI came here for an argumentⓧstartScheduledTask.shⓧ

in memory, and this gets interpreted as

  • argv[0] = ls
  • argv[1] = -l
  • argv[2] = fruit.sh
  • argv[3] = I came here for an argument
  • argv[4] = startScheduledTask.sh

This exact same process happens if you are

  1. typing a java command directly into your primary, interactive shell,
  2. executing a java command that is in a shell script, or
  3. running a shell script by typing a command like ./startScheduledTask.sh directly into your primary, interactive shell,

so this is not the problem.  Any program that cannot handle having its arguments separated by null characters cannot work in Unix & Linux.

TL;DR

Your first command is correct.  "$@" gives you what you want; it is the correct way for a shell script to pass its arguments to a program that it calls.  If you add debug code to your program to loop through its arguments, printing each one on a new line, and/or in brackets (but not all on one line, separated only by spaces), you will see that the "$@" is passing six arguments to the program.


OK, even more:

  • Your class path has asterisks (*s) in it?  Really?  I’m a little out of practice with Java, but that seems odd to me.  Please double-check that you’re doing that correctly for your system.  But, if it works correctly when you type the classpath with asterisks “directly” (i.e., directly into your main shell; your primary, interactive shell; your login shell), then that’s probably not the problem.

    But please humor me and put that string into quotes, anyway.

  • Your problem is too complicated.  When you’re building an airplane, you don’t build the entire plane and then try to fly it.  And then, when it doesn’t fly, you don’t step back and ask, “What’s wrong with the plane?”  No, you test it in pieces.  You need to simplify.

    • Stop running it in the background.
    • Stop saying nohup.
    • Stop redirecting the output.
    • Don’t show your 42-character long shell prompt in your question.
    • Your question is about an argument with spaces in it, so don’t take that out, but it doesn’t have to be 60 characters long with eight spaces.  green banana is a great test value.
    • Try it with arguments to your program not beginning with - (dash).
    • Maybe even comment out the new TaskRunner().run(args) part of your program, leaving only the DEBUG and System.exit(0);.

    None of these should make a difference.  But they are distractions that make it hard to see what’s important.  If you can demonstrate the problem in a minimal test configuration, we can rule out all those other things as being related to the problem.  But, if the problem goes away when you remove the irrelevant things, then one of them was probably causing the problem.

    Also, please stop mixing fake/test data and real data (i.e., fruits and tasks) in the question.

  • Please write this script (call it fruity.sh):

    #!/bin/sh
    
                    # classpath
    CP="/opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/*"
                    # package.name.classname
    PC=wib.runner.TaskRunner
    
    "$JAVA_HOME"/bin/java  -cp "$CP"  "$PC"  "$@"
    

    and run

    ./fruity.sh taskExtRef "green banana"
    

    If the debug says

    …[taskExtRef, green banana]
    

    then the "$@" is working correctly, and the problem lies elsewhere in your script.  Try to find it.  Make one change at a time and see how the behavior changes.  If you can’t figure it out, we may be able to help you, but only if you show us the part of the script that’s causing the problem. 

    But if the debug says

    …[taskExtRef, green, banana]
    

    then let us know.

share|improve this answer
    
thank you, I will have to do a new build and deploy with some proper debugging on Monday. I'm actually heading home now but at least I'm not as crazy as what I thought I am. –  GvD Aug 28 at 6:15
    
After testing the solution its not passing the arguments correctly from the script: The java code prints out the following arguments as passed: After testing the solution its not passing the arguments correctly from the script: The java code prints out the following arguments as passed: [TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD, IPV, -, EOD, Rates, Input, -, Commodities, Volatilities] This was printed using: System.out.println("DEBUG: arguments passed to the main - " + Arrays.toString(args)); –  GvD Aug 30 at 23:27
    
The output is as expected with the fruity script. –  GvD Sep 1 at 0:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.