web-dev-qa-db-ja.com

groovyを使用して、複数のシェルコマンドをどのようにパイプしますか?

Groovyの使用とJava.lang.Processサポート、複数のシェルコマンドを一緒にパイプするにはどうすればよいですか?

次のbashコマンドを検討してください(ユーザー名がfooであると想定しています)。

ps aux | grep ' foo' | awk '{print $1}'

これにより、ユーザー名が出力されます-ユーザーアカウントに関連するいくつかのプロセスの1行。

Groovyを使用すると、 ProcessGroovyMethods のドキュメントとコードで、これを実行して同じ結果を得ることができるはずです。

def p = "ps aux".execute() | "grep ' foo'".execute() | "awk '{print $1}'".execute()
p.waitFor()
println p.text

ただし、これ以外のテキスト出力は取得できません。

def p = "ps aux".execute()
p.waitFor()
println p.text

パイプラインを開始するとすぐに、printlnは何も出力しません。

考え?

14
Les Hazlewood

これは私にとってはうまくいきます:

_def p = 'ps aux'.execute() | 'grep foo'.execute() | ['awk', '{ print $1 }'].execute()
p.waitFor()
println p.text
_

不明な理由により、awkのパラメーターを1つの文字列だけで送信することはできません(理由はわかりません!おそらくbashが別のものを引用している可能性があります)。コマンドでエラーストリームをダンプすると、awkスクリプトのコンパイルに関連するエラーが表示されます。

編集:実際、

  1. "-string-".execute()デリゲートRuntime.getRuntime().exec(-string-)
  2. 'または "でスペースを含む引数を処理するのはbashジョブです。Runtime.execまたはOSは引用符を認識しません
  3. "grep ' foo'".execute()を実行すると、最初のパラメーターとして_'_を使用し、2番目のパラメーターとして_foo'_を使用してコマンドgrepを実行します。これは無効です。 awkも同じ
17
Jérémie B

これを行うと、シェルにそれを整理させることができます。

// slash string at the end so we don't need to escape ' or $
def p = ['/bin/bash', '-c', /ps aux | grep ' foo' | awk '{print $1}'/].execute()
p.waitFor()
println p.text
11
tim_yates

これは私のために働いた

def command = '''
    ps aux | grep bash | awk '{print $1}'
'''
def proc = ['bash', '-c', command].execute()
proc.waitFor()
println proc.text

複数のコマンドを実行する場合は、コマンドに追加できます。

def command = '''
    ls -ltr
    cat secret
'''
def proc = ['bash', '-c', command].execute()
proc.waitFor()
println proc.text
3
Here_2_learn

非同期にしたい場合は、

 proc.consumeProcessOutputStream(new LineOrientedOutputStream() {
        @Override
        protected void processLine(String line) throws IOException {
           println line
        }
    }
    );
0
Gilad Baruchian