私は、基本的に認証回数/カウントについて/var/log/accountpolicy.log*
ログを解析するだけのスクリプト(OSXで実行され、おそらく他には何も実行されない)に取り組んでいます。最初のコマンドは、zgrep
を介して実行されるSudo
であり、これはawk
にパイプされ、awkスクリプトを実行します。コマンドを実行した後、${PIPESTATUS[@]}
を使用して、何かが失敗したかどうか、失敗した場合はどの部分かを判断します。
現在の状態のawkスクリプトは次のとおりです。
#! /usr/local/bin/awk -f
BEGIN {
return_code = 0
if ( length( username ) == 0 ){
return_code = 2
exit return_code
}
rows = 0
}
{
if ( $8 != sprintf("\"%s\",", username ) ) next
rows = rows+1
print $0
}
END {
if ( return_code > 0 ) exit return_code
if ( rows == 0 ) exit 3
}
Awkスクリプトには、いくつかのカスタム値検証および終了コードがあります。戻りコード1、2、および3は、次のことを意味します。
実行例(この質問は特にリターンコードに関連しているため、awkスクリプトからの出力を非表示にします):
$ Sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* 2>/dev/null | awk -v username="${USER}" -f ./parse-accountpoliocy.awk &>/dev/null
$ echo ${PIPESTATUS[@]}
0 0
${PIPESTATUS[@]}
は、Sudo
とawk
の両方が成功したことを示していることがわかります。これは、私がSudoアクセス権を持っていることを知っているので、予想されます。awk変数username
が設定され、ログエントリがあります。
ここで、awk変数username
を存在しないのアカウントに変更すると、awkスクリプトは3
の戻りコードで終了するはずです。
$ Sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* 2>/dev/null | awk -v username="fakeuser" -f ./parse-accountpoliocy.awk &>/dev/null
$ echo ${PIPESTATUS[@]}
0 3
完璧!
上記のコマンドを実行したが、username
awk変数の定義を怠った場合、awkスクリプトshould終了コード2で終了します。
$ Sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* 2>/dev/null | awk -f ./parse-accountpoliocy.awk &>/dev/null
$ echo ${PIPESTATUS[@]}
141 2
ご覧のとおり、awkスクリプトdoes return 2
ですが、何らかの理由で、Sudo
/zgrep
は141
を返します。コマンドのその部分がまったく変更されていないという事実にもかかわらず...そしてこれは私が遭遇している問題です。
([〜#〜] stdout [〜#〜]または[〜#〜] stderr [〜#〜]のいずれかの出力を非表示にせずにコマンドを実行しようとしました。 =)、結果は同じですが、エラーは表示されませんでした:
$ Sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* | awk -f ./parse-accountpoliocy.awk
$ echo ${PIPESTATUS[@]}
141 2
awk
スクリプトの終了コードは、${PIPESTATUS[@]}
内に格納されているSudo
/zgrep
コマンドの終了コードをどのように変更できますか?
_$ echo $((141-128))
13
$ kill -l | grep 13
13 PIPE Broken pipe 29 INFO Information request
$
_
したがって、141は、シェルがPIPE
信号を含む16ビットの終了ステータスワード(wait(2)
を参照)を単一の数値にまとめる方法です。 _exit 3
_の場合、これは発生しませんafterパイプされるデータはawk
によって処理されました(そしてzgrep
にはこれ以上何もありませんパイプ経由でawk
に書き込みます)。代わりに、_exit 2
_は非常に早い段階で発生しますが、zgrep
にはまだawk
にパイプしたいデータがあるため、zgrep
はPIPE
で攻撃されます。消えたawk
に書き込もうとします。