2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ansible Tips: shellモジュールのリアルタイムログ出力をファイルに書き出し、かつshellモジュールにもstdout, stderrをきちんと返す

Posted at

備忘

要件

以下を満たしてAnsible Shellモジュールを使用したい

  • Ansible Shellモジュールにstdout, stderrを正しく戻す
  • かつ、途中経過を確認できる様にログファイルにもstdout, stderrを書き出す
  • かつ、AIX環境(ksh)でも使える(汎用的)

exec で出力先をログフィルにするとShellモジュールに結果が戻せない。
全体に対して| teeを用いる対応では、stdoutとstderrを個別に扱うことが困難。
しかし、名前付きパイプを利用すれば要件を満たすことが可能。

ソリューション

名前付きパイプを使用する

task例

- name: "STDOUT, STDERRをリアルタイムでログに書き出すshellモジュール例"
  shell: |-
    LOGFILE="/tmp/logfile.log"
    STDOUT_PIPE="/tmp/stdout_pipe.$$"
    STDERR_PIPE="/tmp/stderr_pipe.$$"
    mkfifo "$STDOUT_PIPE" "$STDERR_PIPE"
    trap "rm -f '$STDOUT_PIPE' '$STDERR_PIPE'" EXIT
    cat /dev/null > "$LOGFILE"
    tee -a "$LOGFILE" < "$STDOUT_PIPE" &
    tee -a "$LOGFILE" < "$STDERR_PIPE" >&2 &
    exec > "$STDOUT_PIPE" 2> "$STDERR_PIPE"
    set -x
    処理本体
    ...
  • 少し長いので複数行の変数としてどこかにまとめておいても良いでしょう。
  • mkfifoコマンドで名前付きパイプを作成、execでstdout, stderrと接続、teeコマンドにてファイルに分岐させた上で、stdout, stderrに戻すといった流れ。
  • trapを用いてスクリプト終了時に名前付きパイプも削除。
  • 最新のshellの状況さえ分かれば良いだけならLOGFILEをつどnullクリアすればハウスキープもほぼ不要。
  • set -xのデバックモード指定は、処理本体に影響がないことを確認の上、必要に応じて。
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?