Bash 配列 $PIPESTATUS に関する問題

Bash 配列 $PIPESTATUS に関する問題

/var/log/accountpolicy.log*私はデフォルトで認証時間/回数を得るためにログを解析するスクリプト(おそらく他のものではない)を書いています。初期コマンドは awk スクリプトにパイプしてzgrep実行されます。コマンドを実行した後に失敗したものがある場合、その場合はどの部分が失敗したかを確認するために使用しました。sudoawk${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は次のことを意味します。

  1. awkに失敗しました(awk関連の理由で)
  2. awkで解決されたユーザー名が指定されていません。
  3. ユーザー名が指定されましたが、値はありません。

テスト#1(うまく機能)

実行例(この質問は特に戻りコードに関連しているため、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[@]}show とsudoare 成功したことがわかります。これは、sudoアクセス権があり、awk変数が設定され、ログエントリがあることがわかっているawkため、予想される結果です。username

テスト#2(うまく機能)

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

完璧!

テスト#3(質問..)

上記のコマンドを実行しましたが、usernameawk変数定義を省略すると、awkスクリプトがしなければならない戻りコードは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スクリプトはするreturn2ですが、今はコマンドの該当部分がまったく変更されていないにもかかわらず、何らかの理由でsudo/ zgrepreturnです...それが私が経験している問題です。141

出力を隠さずにコマンドを実行してみました(どちらか)。標準出力または標準エラーエラー率)、結果は同じですが、エラーは報告されません。

$ sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log*  | awk -f ./parse-accountpoliocy.awk
$ echo ${PIPESTATUS[@]}
141 2

質問

スクリプトの終了コードは、その中に保存されている/ commandの終了コードをどのように変更しますかawksudozgrep${PIPESTATUS[@]}


環境情報

  • OSxバージョン:10.11.6(エルキャピタン)
  • ヒットバージョン:4.4.12
  • AWKバージョン:GNU Awk 4.1.4

ベストアンサー1

$ echo $((141-128))
13
$ kill -l | grep 13
13   PIPE Broken pipe                   29   INFO Information request
$ 

wait(2)したがって、141は、シグナルを含む16ビット終了ステータスワード(参考文献を参照)を単一の数値に統合するシェルPIPEの方法です。exit 3後ろにパイプに接続されているデータの処理が完了しました(パイプを介して書き込むawkことはもうありません)。zgrep代わりに、パイプするデータがまだ残っている間は最初に発生するため、awk消えたデータを書き込もうとするとaが発生します。exit 2zgrepawkzgrepPIPEawk

おすすめ記事