リモートでジョブを開始できるコマンドラインインターフェイスを備えたCIサーバーを持っています(jenkins
CIサーバーとjenkins-cli.jar
ツール)。
仕事を始めた後、私はtail -f
ログ(乱雑なコマンドでは申し訳ありません):
ssh -t my-jenkins-Host.com "tail -f \"/var/lib/jenkins/jobs/$job_name/builds/\`ls -ltr /var/lib/jenkins/jobs/$job_name/builds/ | grep '^l' | tail -n 1|awk '{print \$9}'\`/log\""
ジョブが正常に完了した後、通常は少なくとも5分後、出力に次の行が表示されます。
Finished: SUCCESS
この時点でログのテーリングを停止する良い方法はありますか?つまり、tail_until 'some line' my-file.log
コマンド?
BONUS:SUCCESSが一致したときに0を返し、FAILUREが一致したときに1を返す回答を提供できる場合、追加のクレジット、およびあなたの解決策はMacで動作します! (私はbsdベースであると私は信じています)
tail -f
をsed
に追加して、検索している行が見つかると終了するように指示します。
tail -f /path/to/file.log | sed '/^Finished: SUCCESS$/ q'
sed
は、デフォルトで処理する各行を出力し、その行を検出した後に終了します。 tail
プロセスは、次の行を書き込もうとして、出力パイプが壊れていることを検出すると停止します
tail -f my-file.log | grep -qx "Finished: SUCCESS"
-q
、静かを意味し、一致が見つかるとすぐに終了します
-x
はgrep
を行全体に一致させます
2番目の部分については、
tail -f my-file.log | grep -m 1 "^Finished: " | grep -q "SUCCESS$"
-m <number>
numberが一致した後にgrepを停止するように指示します
また、grep -q
の終了ステータスは、SUCCESS
が行末にある場合にのみ0
になります。
すべての出力を表示したい場合、grep -q
は使用できませんが、それでも実行できます
tail -f my-file.log | grep -m 1 "^Finished: "
FAILURE
が表示された場合、終了ステータスを1に設定する以外はすべて実行します。
@Mrozekのコメントを含む@Mikelの回答のバリエーション(コメントには返信しましたが、まだ十分な権限がないと思います)
tail -f my-file.log | tee >( grep -qx "Finished: SUCCESS" )
@Mikelのソリューションを使用しても、画面に出力が表示される
私はここで答えが好きではなかったので、自分で答えることに決めました。このbashスクリプトはすべての基準を満たし、失敗時に1を終了するためのボーナスが含まれています。
#!/bin/bash
while IFS= read -r LOGLINE || [[ -n "$LOGLINE" ]]; do
printf '%s\n' "$LOGLINE"
[[ "${LOGLINE}" == "Finished: SUCCESS" ]] && exit 0
[[ "${LOGLINE}" == "Finished: FAILURE" ]] && exit 1
done < <(timeout 300 tail -f my-file.log)
exit 3
また、終了コードが3になるタイムアウト機能も含まれています。システムにタイムアウトコマンドがない場合は、Anthony Thyssenからtimeout.shスクリプトを入手してください。
http://www.ict.griffith.edu.au/anthony/software/timeout.sh
以下のコメントに従って、エスケープ文字の展開を停止するようにログ印刷を更新し、標準の「読み取り」のすべての機能を含めました。完全な「読み取り」の詳細については、 https://stackoverflow.com/a/10929511 を参照してください。 EOFチェックはここでは必要ありませんが、完全を期すために含まれています。
sed
とgrep
とそれらのオプションに問題があったので、私はone with bash conditions
tail -f screenlog.* |
while IFS= read line;
do
echo $line;
if [[ $line == *Started\ Application* ]];
then pkill tail;
fi;
done
あなたもやってみます
grep -q 'App Started' <(tail -f /var/log/app/app.log)
ここにpythonスクリプト--ほぼが私がやりたいことをします(以下の警告を参照))です:
import sys,re
def main():
re_end = re.compile(sys.argv[1])
re_fail = re.compile(sys.argv[2]) if len(sys.argv) > 2 else None
for line in sys.stdin:
sys.stdout.write(line)
if re_end.match(line):
sys.exit(0)
Elif re_fail and re_fail.match(line):
sys.exit(1)
if __name__ == '__main__': main()
警告:
入ってくると線は印刷されません...それらはグループで印刷されます...いくつかのバッファリングが起こっているようです
私はこれを自分のパスまたは何かにスクリプトとしてインストールする必要があるので、それは不便であり、滑らかなワンライナーを好みます:)