2011-06-10 9 views
3

私はstdoutとstderrに出力するプログラムを持っていますが、正しい方法でそれらを使用していません。いくつかのエラーはstdoutに行きます、いくつかはstderrに行きます、エラー以外のものはstderrに行き、stdoutに関する多くの情報を表示します。私が行うためのパイプラインを作りたい、この修正するには:ファイル$logfilestdoutとstderr io-redirectionを使用してプログラムから正常なエラー/警告メッセージを出力するにはどうすればよいですか?

  1. 保存(標準エラー出力と標準出力の両方から)$cmdのすべての出力を(それを画面に印刷されません)。
  2. stderrとstdout(警告|エラーから空行まで)のすべての警告とエラーメッセージを除外し、 "エラー"ワードのみを色付けします(出力をstderrにリダイレクトします)。
  3. ステップ2の出力をファイル$logfile:r.stderrに保存します。
  4. コマンドから正しい終了コードを使用して終了します。私は多くのことを試みたが、それは仕事を得ることができない

    $!/bin/zsh 
    # using zsh 4.2.0 
    setopt no_multios 
    
    # Don't error out if sed or grep don't find a match: 
    alias -g grep_err_warn="(sed -n '/error\|warning/I,/^$/p' || true)" 
    alias -g color_err="(grep --color -i -C 1000 error 1>&2 || true)" 
    alias -g filter='tee $logfile | grep_err_warn | tee $logfile:r.stderr | color_err' 
    
    # use {} around command to avoid possible race conditions: 
    { eval $cmd } 2>&1 | filter 
    exit $pipestatus[1] 
    

は、これまでのところ、私はこれを持っています。 $cmdが呼び出すシェルスクリプトです:

  1. のみ標準入力フィルタ

注意に入る:私は私の問題は、現在あるなど、「Zシェルにバッシュから」多くの記事を読みました接頭辞は/usr/bin/time -pです。これはパイプラインの問題を引き起こすと思われるので、すべての出力がパイプに入る{…}にコマンドをラップします。

答えて

1

を理解していない。

#!/bin/zsh 
# using zsh 4.2.0 
setopt no_multios 
#setopt no_errexit # set -e # don't turn this on 

{ eval $cmd } 2>&1 | 
tee $logfile | 
sed -n '/error\|warning/I,/^$/p' | 
tee $logfile:r.stderr | 
grep --color -i -C 1000 error 1>&2 
exit $pipestatus[1] 

一部私を混乱させたのは、stdoutとstderrを混在させてインターリーブし、sed -n '/error\|warning/I,/^$/p'(これは次の空行に||警告を出力する)が期待した以上に印刷されていて、コマンドwasn

2

私はzshを利用できません。

私はあなたの{..}のdステートメントが正しくないことに気付きました。

「}」の前には常にセミコロンが必要です。

私がbashで追加したとき、stderrがstdoutにリダイレクトされていたことを私が満足していることがわかりました。

私がいない

{ eval $cmd ; } 2>&1 | filter 
# ----------^ 

また、あなたはファイル$ログファイルに保存する$ CMDのすべての出力(フォームの標準エラー出力 とstdout)を

を書いた

をお試しくださいあなたのコードの$ logfileの言及を参照してください。 (標準エラー出力ストリームのspecficityを失っている間) あなたは

yourCommand 2>&1 | tee ${logFile} | .... 

と私はこれが役に立てば幸い、ログファイルにすべての出力を得ることができる必要があります。

P.S.あなたが新しいユーザーのように見えるように、あなたがそれを受け入れられたものとして覚えておいてください、そして/または役に立つ答えとして+(または - )を付けるのを助ける答えを得たら。

+0

'{eval $ cmd}'はzshで動作します。 '$ logfile'は' filter 'エイリアス。 – Gilles

+0

Doah、それを指摘してくれてありがとう。 – shellter

1

スクリプトでエイリアスを使用しないで、関数を使用します(グローバルエイリアスは特に問題を探します)。実際にここで機能が必要なわけではありません。 set -eの下で実行している場合を除き、|| trueも必要ありません。その場合は、ここでオフにしてください。それ以外は、スクリプトは大丈夫です。それは何が窒息ですか?

{ eval $cmd } | 
tee $logfile | 
sed -n '/error\|warning/I,/^$/p' | 
tee $logfile:r.stderr | 
grep --color -i -C 1000 error 1>&2 
exit $pipestatus[1] 

あなたがsed式の意味を理解できません。私はかなりオリジナルのポストはとてもsは必要とされていない|| true「をset -eをオフにする(ジルによる最適化を除いて、ほとんどが正しかったあなたの条件2.

+0

こんにちはGilles、sed行は、すべての行に 'error'または 'warning'とそれに続くすべての行を空行まで表示します。これは要件2の最初の半分です。他の半分は 'grep --color ... 1>&2'です。 – dailyglen

+0

Gilles、チップのおかげで、 '||本当です。私は 'setopt errexit'をセットしました(' set -e'と同じです)。 – dailyglen

関連する問題