0

シェル スクリプトを使用して Java プログラムを呼び出しています。渡す Java プログラムを呼び出すときに、ディレクトリへのパスを持つ -Dargument を渡します。この -D 引数は、ファイルから読み取られます。このパスにスペースが含まれていると、問題に直面しています。私は引用符と引用符をエスケープしてみましたが、どちらもうまくいきません。

ここに私のシェルスクリプトコード、test.shがあります

   D_ARG=`(tr '\r\n' ' ' < argument.dat)
  \#executing java code by passing above argument
   java ${D_ARG} TestProgram

以下は私の引数ファイル、argument.dat です。

  -Dargument1="/Path /To A/File"

set -x を使用してエコーを設定すると、シェルがそれを

  '-Dargument1="/Path' '/To' 'A/File"'

スペースに遭遇したときに一重引用符を追加すると、「/To」クラスが見つからないという例外が発生します。この問題を解決する方法。どんな提案や助けも本当に価値があります。

4

3 に答える 3

2

これを試して:

ARGS=

# Do nothing if there are no spaces; if there are spaces, surround with quotes
for arg in $(perl -pe '/ / or next; s/^/"/; s/$/"/' argument.dat); do
    ARGS="$ARGS $arg";
done

java $ARGS TestProgram

これは基本的に、行にスペースが含まれるたびに引用符で囲まれるため、-Da=b cに変換されるという効果があり"-Da=b c"ます。

"-Da=b c"は と厳密に同等-Da="b c"であるか、さらに奇妙に見える形式であることに注意してください。

  • '-Da='b\ c;
  • -D"a=b "c;
  • などなど

唯一重要なことは、入力フィールドのセパレーターである文字がエスケープされることです。はい、これは合法です:

alias l"l=ls"\ -l
于 2013-01-11T11:16:19.560 に答える
0

「/Path /To A/File」のスペースをエスケープする可能性があります。ただし、これは良い解決策ではありません。多くの場合、次のようなコマンドを定式化する可能性があるためです。

system(argv[1]);/* Example is  C specific; 
      but you understand the loop-hole imparted by single escaping.
      You may require multilevel escaping, based on your implementation. OR
      We may have to escape the string, every time it is dereferenced.
      */

Linux システムでのより良いオプションは、シンボリック リンクを作成することです。

ln -s "/Path /To A/File" /tmp/file

& 引数ファイルで、問題-Dargument1="/tmp/file"
のファイルが 1 つしかない場合は、このアプローチを使用"/Path /To A/File"します。


別のアプローチは使用していますmount --bind

mkdir /tmp/myfiles && mount --bind "/Path /To A" /tmp/myfiles

& 引数ファイルで、使用-Dargument1="/tmp/myfiles/File"
このアプローチはにマウント"/Path /To A"され /tmp/myfilesます。その中のすべてのファイルとディレクトリ構造は保持されます。

于 2013-01-11T12:09:27.457 に答える
0

スクリプトは、引用符を保持し、単一引用符を追加しないコマンド eval と一緒に使用すると機能しました。

  D_ARG=`(tr '\r\n' ' ' < argument.dat)
 \#executing java code by passing above argument
  eval java ${D_ARG} TestProgram
于 2013-01-11T16:34:09.337 に答える