2012-03-01 10 views
3

こんにちは私は特有の問題を抱えており、私は難しいと思っています。(解決策は意図しています)解決策があります。パイプコマンド "stderr"コマンドにFind

$> find ./subdirectory -type f 2>>error.log 

私はエラーを取得し、何かのように、「見つける:./subdirectory/noideaを:アクセス許可が拒否されました」このコマンドから、これはerror.logににリダイレクトされます。

方法はあります私はできパイプのerror.logにリダイレクトする前に、別のコマンドへstderrを?私は

私はパイプにしたい
$> find ./subdirectory -type f 2 | sed "s#\(.*\)#${PWD}\1#" >> error.log 

のみstderrのような何かを行うことができるようにしたい

sedコマンドとfindコマンドエラーの全体のパスを取得します。

私は配管がここでは機能しないと知っていますが、おそらく正しい方法ではありません。

私の問題は、私はSTDOUTstderrのの両方を必要とし、両者が同時に異なるものを通して処理する必要があります。

編集: 私の問題を少し修正。今

、私はこのシェルスクリプトでは、solve_problem.sh

をシェルスクリプトを持って、私は次のコード

ErrorFile="error.log" 
for directories in `find ./subdirectory -type f 2>> $ErrorFile` 
do 
    field1=`echo $directories | cut -d/-f2` 
    field2=`echo $directories | cut -d/-f3` 
done 

同じ問題が、シェルスクリプトの内部を持っています。 "find:./subdirectory/noidea:Permission denied"エラーは、$ ErrorFilestdoutに変数$ディレクトリが割り当てられるはずです。

答えて

2

パイプ標準エラー出力と標準出力 - this postから取られたアイデア:

(find /boot | sed s'/^/STDOUT:/') 3>&1 1>&2 2>&3 | sed 's/^/STDERR:/' 

出力例:

STDOUT:/boot/grub/usb_keyboard.mod 
STDERR:find: `/boot/lost+found': Brak dostępu 

3>&1 1>&2 2>&3スワップ標準エラー出力とstdoutのようなバッシュリダイレクト。

私はこのように見て、あなたのサンプルスクリプトを変更します:私は二回標準出力&標準エラー出力を入れ替え

#!/bin/bash 
ErrorFile="error.log" 
(find ./subdirectory -type f 3>&1 1>&2 2>&3 | sed "s#^#${PWD}: #" >> $ErrorFile) 3>&1 1>&2 2>&3 | while read line; do 
    field1=$(echo "$line" | cut -d/-f2) 
    ... 
done 

注意してください。

小さな追加のコメント - マニュアルページを見つけるには-printfオプションを見てください。それはあなたにとって有用かもしれません。

+0

これは便利なテクニックですが、注意が必要です。特に、findはstdoutに "STDERR:"と書かれていて、findのstdoutはstderrに "STDOUT:"という接頭辞が付いたエラーメッセージが表示されます。 –

+0

@kupson:本当に便利な解決策です。しかし私はそれが私のシナリオではうまくいくかどうかはわかりません。 私は '(find ./subdirectory/ -type f)3>&2 2>&1 1>&3 |のようなものを試しました。 ?\(find:\)\(。* \)?\ 1 $ {PWD}/\ 2? >> $ ErrorFile'しかし、これは私のためには機能しませんでした。エラーはログファイルにリダイレクトされますが、_stdout_はforループの変数に割り当てられません。私は問題を更新しました。 – latestVersion

+0

@latestVersionこの状況ではwhileループを使用します。 – kupson

1

stderrstdoutにリダイレクトする必要がある場合は、パイプ内の次のコマンドが入力として取得されるように、2>&1を使用できます。

詳細については、all about redirectionハウツーをご覧ください。

編集:

$ find . -type f 2>&1 | sed '/^find:/{ 
> w error.log 
> d 
> }' 

この例では:

    あなたはパイプにさらに stdoutを渡す編集する必要がある場合でも、エラーメッセージをフィルタリングし、それらをファイルに書き込むために sedを使用することができます
  • findのコマンド
  • sedのコマンドエラーfind正規表現に一致するファイルは、ファイル(w error.log)に書き込まれ、出力(d)から削除されます。
  • パイプラインに続くパイプラインのコマンドは、findからの出力を受け取ります。

注:これはfindからのすべてのエラーメッセージがfind:で始まるため、lonとして機能します。それ以外の場合、sedの正規表現はすべての場合に適切に一致するように変更する必要があります。同時に

+0

配管自体が無効です私の場合、** stderr **は "sed"コマンドを、** stdout **はスクリプトの中で別のコマンドを実行したいと思っています。 – latestVersion

+0

これはどういう仕組みか分かりません。多分あなたは私がここで起こっていることを理解するのを助けることができます。 また、 'sed'コマンドで代用することができますか? – latestVersion

+0

私は説明を編集してより明確にしました。私はそれが助けて欲しい – jcollado

0

あなたは仕事に表示される、(bashの上で)これを試すことができます:

find ./subdirectory -type f 2> >(sed "s#\(.*\)#${PWD}\1#" >> error.log) 

これは以下のん:

  1. 2>は、SEDを実行している(
  2. >(...)に標準エラー出力プロセス置換をリダイレクトします、error.logに追加)
+0

このソリューションはコマンドラインで動作します。しかし、シェルスクリプトで試したときに構文エラーが発生しました。とにかくこれで私を助けることができますか? – latestVersion

+0

@latestVersion:(bash 4.2.20の)投稿したときに回線を試しましたが、動作するようです。 '2>'の後にスペースがなければならないことに注意してください。そうしないと、構文エラーが発生します。 (実際には '>(...)'の前にスペースが必要ですが、この場合は同じことです)。 – Hasturkun