0

JavaからLinuxコマンドを実行しているときに機能しない場合、この問題について誰かが助けてくれます。

process3 = Runtime.getRuntime().exec(new String[] {"ls",
                    "-1s", 
                     "--block-size=1",
                      TStamp+"/received/i*.*",
                      "$dir|",
                      "awk",
"'{print $2\"\\t\"$1}'",
                           ">>",
                  "./"+TStamp+"/qa/manifest_QAG.txt"});
InputStream in1 = process3.getInputStream();              
BufferedReader br1=new BufferedReader(new InputStreamReader(in1));
String line1 =null;
while((line1=br1.readLine())!=null)
{
System.out.println(line1);
} 

Edit1: ファイルを一覧表示し、manifest_QAG.txt でマニフェストを生成しようとしています。

実際のコマンドは Linux で動作します:

ls -1s --block-size=1 20130328094916142/received/is*.* $dir| awk '{print $2"\t"$1}'

Edit2:例外は発生せず、ファイルmanifest_QAG.txtも作成されていません

編集3:

4

3 に答える 3

2

lsコマンドは Java ではなく、例外ではなくエラー メッセージSTDERRと終了コードで通信するため、例外は発生しませんでした。

実際には、コマンドを入力したときにシェルが何をするか、およびコマンドが何をするかを理解する必要があります。したがって、このようなシェルコマンドライン

ls -1s --block-size=1 20130328094916142/received/is*.* $dir| awk '{print $2"\t"$1}'

シェルによって次のように処理されます。

  • シェル:20130328094916142/received/is*.*ファイル名のリストに展開します
  • シェル:$dirパーツをファイル名のリストに展開します
  • シェル:ls引数を指定してコマンドを 実行します
    • ls
    • -1s
    • --block-size=1
    • 個別の引数として展開された各ファイル名
  • shell:awk引数を指定してコマンドを 実行
    • {print ...}
  • shell: の出力lsを の入力に接続しますawk
  • ls: 引数を評価する
  • awk: 各行を読み取り、指定されたスクリプトで処理し、結果を出力します。

ご覧のとおり、環境変数とワイルドカードの展開は、 ではなくシェルによって行われlsます。

Java に戻る: シェルのように引数を処理executeしません。あれは君次第だ。したがって、呼び出しは、おおよそ次のようなシェルと同等です。

ls '-1s' '--block-size=1' '20130328094916142/received/is*.*' '$dir' '|' 'awk' '{print $2"\t"$1}'

パイプを含め、すべてが引用符で囲まれているため、シェルによって何も展開されません。

これまでのところ問題。解決策は何ですか?

  • シェルをエミュレートし、Java で展開できます。これを楽しんでください。(つまり、これは本当の解決策ではありません)。
  • の代わりに Java からシェルを呼び出すことができますls

後者は次のようになります。

通常、シェルには1 つの-cコマンド文字列を指定できるオプションがあり、実際に入力されたコマンド ラインと同じ方法で評価されます。

したがって、次のようにコマンドを呼び出します

String[] args = {
    "/bin/sh",
    "-c",
    "ls -1s --block-size=1 20130328094916142/received/is*.* $dir| awk '{print $2\"\t\"$1}'"
};
Process process3 = Runtime.getRuntime().exec(args);

awkコマンドを正しく引用するには、さらに作業が必要になる場合があります。

于 2013-03-28T15:24:30.523 に答える
0

パイプ (|) は ls の引数ではなく、シェルの機能です。そのようなパイプを Runtime#exec で使用したい場合は、代わりにシェルを起動し、シェルに解析して実行させたいコマンド文字列を引数として渡す必要があります。

ただし、何か不足していない限り、簡単なファイル操作や文字列操作のために外部ツールを呼び出すよりも、Java コードを使用してディレクトリを一覧表示し、マニフェストを作成する方がおそらく簡単でしょう。

于 2013-03-28T15:21:04.360 に答える
0

ここにタイプミスがあると思います

/received/i*.* is different from one that is in linux command /received/is*.*

それが役に立てば幸い

于 2013-03-28T15:06:21.217 に答える