質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Groovy

Groovyは、Java用のオブジェクト指向型プログラミング言語です。PythonやRuby、Perl、そしてSmalltalkに似た特徴を有する動的な言語です。

Q&A

解決済

1回答

3957閲覧

Groovyのシェルコマンドを用いた値の取得の仕方がわからない

span

総合スコア32

Groovy

Groovyは、Java用のオブジェクト指向型プログラミング言語です。PythonやRuby、Perl、そしてSmalltalkに似た特徴を有する動的な言語です。

0グッド

0クリップ

投稿2020/05/27 19:20

編集2020/05/29 16:29

Groovy初学者で困っております...

task compile << { println 'We are doing the compile.' } compile.doFirst { def bool = ps aux | grep "プロセス名" | grep -v grep | wc -l if (bool) { throw new StopExecutionException() } }

上記のようにps aux | grep "プロセス名" | grep -v grep | wc -lプロセスを実行中かどうかを判断し、もし起動プロセスが無い場合にはtask compileの中の処理をスキップしたいと考えています。
しかしどのような書き方をすればシェルコマンドから値が取り出せるのかがわかりません。

初歩的なことで大変申し訳ないのですがどのようにすれば取得できるかご教示いただければ幸いです。
また、もしももっと良い書き方等ありましたらご指摘いただければ嬉しいです...申し訳ありませんがよろしくお願いいたします。


追記

compile.doFirst { def bool = 'ps aux'.execute() | 'grep hoge'.execute() | 'grep -v grep'.execute() | 'wc -l'.execute() if (bool.text == "0") { throw new StopExecutionException() } }

上記のように.execute()でシェルコマンドの実行は上手くいったのですがif文が上手く動いてくれません。
Groovyではこのようなif文の書き方はダメなのでしょうか...?


追記

def process = "ps aux | grep \"プロセス名\" | grep -v grep | wc -l".execute(); println '確認' println process.getText()

上記のようにしたところコンソールには

>>>確認 >>>

のように表示されます。process.getText()は空のようです。
コンソールに直接 ps aux | grep \"プロセス名\" | grep -v grep | wc -l を打ち込むと
プロセス起動時には 2 が返り プロセスをkillした状態だと 0 が返ります

##バージョン情報
Groovy 2.4.15
java 1.8.0_202


追記

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YT0014

2020/05/29 02:04

Groovyとjavaのバージョン情報を、質問に追記してください。
span

2020/05/29 10:24

ご指摘ありがとうございます!追記させていただきましたのでよろしければご確認いただけましたら幸いです。
guest

回答1

0

ベストアンサー

シェルコマンドの実行は、シェル上で指定する文字列Objectのexecute()メソッドになります。

def process = "ps aux | grep \"プロセス名\" | grep -v grep | wc -l".execute();

なお、execute()の返り値はProcessのインスタンスで、出力結果を文字列で取得する場合は、getText()を使います。

if (process.getText().equals("0")) { throw new StopExecutionException(); }

となるかと思います。

なお、申し訳ないのですが、上記コードは未検証です。

Groovy Documents

追記:検証結果を受けて
色々試してもらった結果、以下のコードで、ご要望の処理が行えそうです。

Groovy

1compile.doFirst { 2 def process = 'ps aux'.execute() | 'grep プロセス名'.execute() | 'grep -v grep'.execute() | 'wc -l'.execute() 3 4 def result = process.getText() 5 6 if (result.equals("0")) { 7 throw new StopExecutionException() 8 } 9}

ドキュメントからは読み取れなかったのですが、getText()は、呼び出す度に値が変わる可能性が高いので、呼出しは1度だけ。
文字列の比較なので、equals()を用いる。
呼出し処理に掛かる時間が十分短いか、getText()で処理待ちをしているかしているようなので、waitForOrKill()は不要と思われます。

投稿2020/05/28 13:18

編集2020/05/29 15:53
YT0014

総合スコア1750

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

span

2020/05/28 15:19

ご回答いただきましてありがとうございます。 いただいた内容で検証してみたところ def process = "ps aux | grep \"プロセス名\" | grep -v grep | wc -l".execute(); println '確認' println process.getText() の結果コンソールに表示されるのは >>確認 >> という結果でprocess.getText()は空っぽのようでした... 大変申し訳ありませんがこちらご教示いただけると幸いでございます。よろしくお願いいたしますm(_ _)m
span

2020/05/28 15:21

追記になりますがプロセスの起動中にコンソールに ps aux | grep \"プロセス名\" | grep -v grep | wc -l を直接打ち込むと 2 が返ります プロセスをkillした後だと 0 が返ります
YT0014

2020/05/29 02:19

Processクラスに、waitForOrKill()などのメソッドがあることから、execute()は、処理を起動した時点で値を戻しているでしょう。実行そのものは、別プロセスとして処理されているはずです。 その為、終了を確認しないままにgetText()を呼んでも、値が設定されていない状態になります。 間に、waitOrKill()を、20秒待ちくらいで呼んでみてください。
span

2020/05/29 10:17

def process = 'ps aux | grep "storybook" | grep -v grep | wc -l'.execute() process.waitForOrKill(2000) println process println "getText = ${process.getText()}" で試してみましたところコンソールは > java.lang.UNIXProcess@35ef939f > getText = でやはり空のようでした...waitForOrKill()の書き方等間違っているのでしょうか... お手数ですがご教示いただけると幸いございます。
YT0014

2020/05/29 11:52

実行に失敗しているようですね。パイプの方法が間違っている可能性を考えて、process = 'ps aux'.execute(); に変更して、waitForOrKill()の前後で、getText()の内容を表示してみてください。 また、同様に、spanさんが最初に提示された、 process = 'ps aux'.execute() | 'grep hoge'.execute() | 'grep -v grep'.execute() | 'wc -l'.execute(); での実行結果を、getText()、waitForOrKill()、getText()で確認してみてください。 実証環境が用意できないので、お手数おかけします。
span

2020/05/29 15:33 編集

こちらこそ申し訳ありませんご教示いただき非常に助かっております。 本当にありがとうございます! 以下実行の内容になりますので大変お手数ですがご確認ください。 def process = 'ps aux'.execute(); println "1" println "getText1 = ${process.getText()}" process.waitForOrKill(2000) println "2" println "getText2 = ${process.getText()}" とした結果コンソールの内容は > 1 > "ものすごく長いログ" > 2 > と二つ目のgetText2は空でした。 def process = 'ps aux'.execute() | 'grep プロセス名'.execute() | 'grep -v grep'.execute() | 'wc -l'.execute() println "1" println "getText1 = ${process.getText()}" process.waitForOrKill(2000) println "2" println "getText2 = ${process.getText()}" とした結果コンソールの内容は > 1 > getText1 = 0 > 2 > でgetText2は表示されませんでした。しかしやはり if (process.getText().equals("0")) { ... } の部分は反応しておりませんでした(getText1の0の左の余白が気になりました) ちなみに > FAILURE: Build failed with an exception. > * Where: "ファイルディレクトリ/実行ファイル名" line: 24(println "getText2 = ${process.getText()}"が記述されている行) とも出ておりエラーが出ているようでした。 お手数ですがご確認よろしくお願いいたしますm(__)m
YT0014

2020/05/29 16:00

テスト結果、ありがとうございます。回答に修正を加えました。 今回、私から提案した修正や確認をいたしましたが、このような試行錯誤をご自身で考え、エラーメッセージなどの結果も踏まえ、修正していくのが、実務でのプログラミングです。Groovyは、日本語情報も少ないため、苦労が多いと思いますが、がんばってください。
span

2020/05/29 16:25

度々申し訳ありません... compile.doFirst { def process = 'ps aux'.execute() | 'grep プロセス名'.execute() | 'grep -v grep'.execute() | 'wc -l'.execute() def result = process.getText() assert "0" == result if (result.equals("0")) { throw new StopExecutionException() } } とした結果コンソールでは > assert "0" == result | | | 0 false でやはりif文は正常に動作していないようでした.. こちらは取得してきた値がやはり何かおかしいのでしょうか...なんどもお伺いしてしまっており申し訳ありませんm(__)m
span

2020/05/29 16:30

テキストではスペースが削除されてしまい上手く伝わらなかったので画像を追記に貼らせていただいたのですが0の横に何か余白があるような所に違和感を感じております...
YT0014

2020/05/29 16:48

1.Stringの場合、== は、同一オブジェクトの場合にtrueで、文字列内容が同一でも、trueにはなりません。== と equals()の違いを理解してください。 2.空白(または空白に見える何か)があるようならば、文字列長:size()を確認したり、decodeHex()でbyte配列に変換して、文字コードを確認してみるなりしてみてください。 文字コードがわかれば、replaceAll()などで削除することもできるかと。
span

2020/05/30 05:24

ありがとうございます理解いたしました!何度も対応していただき本当に感謝ですありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問