2009-04-13 27 views
28

私のJavaコマンドライン引数では、スペースの後の文字は無視されます。例えば、Javaのコマンドライン引数のスペース

java test.AskGetCampaignByName "Dummy books" 

私は最初の引数(args [0])を "Dummy"として取得します。一重引用符も役立ちません。 誰かがこれに対する回避策や修正を知っていますか?私の端末の設定のためにそれができますか? My $ TERMはxtermで、$ LANGは "en_IN"です。

答えて

53

引数はシェルによって処理されます(私はあなたがLinuxの下でbashを使用していると仮定しています)。あなたは既に議論を引用しているので、それはうまくいくはずです。私が考えることができる唯一の可能な説明は、あなたのjavaコマンドがラッパースクリプトであり、実際のプログラムに渡すときに引数のエスケープを駄目にする場合です。これは簡単ですが、正しく行うには少し難しいかもしれません。

正しいラッパースクリプトでは、すべての引数が${1+"[email protected]"}として渡される必要があります。他のバージョンは、埋め込みスペースを適切に処理できるという点でバグが多い可能性があります。これは適切であることは珍しくありませんが、$2などの出現も面倒であり、埋め込みスペースを正しく処理するためには"$2"(またはおそらく${2+"$2"})と書かれていなければなりません。

直感的ではない構文の理由${1+"[email protected]"}は、元の$*がすべての引数を埋め込みスペースのために機能しなかった"$1 $2 $3 ..."として結合しているためです。そして、"[email protected]"が導入され、(正確に)すべてのパラメータに対して"$1" "$2" "$3" ...に拡張され、パラメータが与えられていなければ、何も展開されません。残念ながら、"[email protected]"は、引数がなくても""に展開され、${1+"[email protected]"}という巧妙な(しかしそれほど読み難い)ハッキングが発明されました。$1が設定されている場合、"[email protected]"のみが展開されます引数がない場合の拡張を避ける)。私のラッパーの仮定が間違っている場合

あなたはstraceの

strace -o outfile -f -ff -F java test.AskGetCampaignByName "Dummy books" 

でデバッグや引数をexecveのために渡されているものを見つけるために試みることができます。 「strace /bin/echo '1 2' 3

execve("/bin/echo", ["/bin/echo", "1 2", "3"], [/* 93 vars */]) = 0 
brk(0)         = 0x2400000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075b000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075a000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/usr/lib64/alliance/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 
stat("/usr/lib64/alliance/lib/tls/x86_64", 0x7fff08757cd0) = -1 ENOENT (No such file or directory) 
open("/usr/lib64/alliance/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 
... 
+1

ありがとうたくさんのhlovdal! これはまさにそのケースでした。私たちは、クラスパスなどを設定するant buildを介して実行可能ファイルを生成します。そして、スクリプトで "java @"を使用していました。 $ {1 + "@"}を代入すると問題が解決しました。私の例では、javaを直接使用して誤解を招いて申し訳ありません。 – ashweta

0

プログラムで定位置より多くの引数(=コマンドラインの使用が重要な場合)が必要な場合は、オプションとスイッチを考慮する必要があります。このためにApache Commonsは素晴らしいlibraryを持っています。

0

ユーザーが使用できるjavaコマンドが適切なJVMを「どこかに」見つけ出し、適切にそれを呼び出すラッパーである場合は、オペレーティングシステムの配布を使用しているようです。

もしそうなら、実際のJava実行可能ファイルを呼び出すとき、引数を適切にエスケープしない可能性が非常に高いです。

どのような分布を使用しますか?

+0

私のWindowsマシン'で "Hello World" の "Hello World" の "Hello Worldのは、"(引数[0(/ 1)としてピックアップされます/ 2)] == "hello world"であり、Linuxではこれは単純に機能しません(私はあまり気にしていなかったので、*私がやっていることを覚えていません)。しかし、私はこれに対する解決策を見てうれしいです。ご質問ありがとうございます。 @ThorbjørnRavn Andersen、詳しく教えてください。 JVMの呼び出し方法を変更するにはどうすればよいですか? –

-3

この質問を実行しているから、例は少し古いですが、なぜあなたは自分のJavaプログラムで引数を再構成していませんか?

StringBuilder allArgs = new StringBuilder(); 
for (int i=0; i < args.length; i++) 
{ 
    //System.out.println("arg"+i+": "+args[i]); 
    allArgs.append(args[i]+" "); 
} 
//Parse out the args the way you wish using allArgs 
+0

を意味すると仮定しました。 'Dummy books'と' books'の間に 'java test.AskGetCampaignByName"ダミーブック "複数の空白があるためスタックオーバーフローが単一のスペースとして出力されるので、ここで見ることはできません。 ..) – leemes

+0

'java'はシェルからコマンドライン引数を適切に取得する必要があるためです。 – Olathe

1

あなたはちょうどこのようなスペースをエスケープする必要があります。

normal String: "Hello World!" 
escaped String: "Hello" "World!" 

私のために働きました。

私の環境: `コマンドライン引数として渡された

23:39:19 [email protected]:/Users/Zarathustra~$bash -version 
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11) 
Copyright (C) 2007 Free Software Foundation, Inc. 
+2

あなたは何もエスケープしていませんでしたが、あなたはちょうど1つの議論を2つの議論にぶつけましたが、それはOPが求めていたものではありません。スペースはエスケープする必要はありませんが、単に引用する必要があります。 –

関連する問題