次のコマンドは結果を提供しませんでした。grep
ファイルからエラー行を抽出してテーブルに挿入したいと思います。
動作しないコマンド:
tail -f logfile.log | grep ERROR|while read msg; do psql -d testdb -c insert into t values('$msg'); done
しかし、grep ERROR
コマンドからコードを削除すると、期待どおりに機能します。何が起こったのか分からない?
うまく動作するコマンド:
tail -f logfile.log|while read msg; do psql -d testdb -c insert into t values('$msg'); done
ファイルに次のデータがあると想定できます。
ERROR
sql committed
ERROR
ERROR
error
...
答え1
2つ:
質問で書かれたように
$msg
一重引用符を使用したため、コードはリテラル文字列(有効な場合)を挿入します。代わりに二重引用符を使用してください。ここでは、文全体を二重引用符で囲みました。これにより内部が拡張されます$msg
。シェルコードはまだ脆弱です。理想的には、単一または他の特殊文字によって文が破損しないように(またはより悪い場合は参照)、grep
文字列を適切に削除する必要があります。$msg
'
ユーザーの意見カス次のような)。tail -f logfile.log | grep -F 'ERROR' | while read msg; do psql -d testdb -c "insert into t values('$msg')" done
また、固定文字列を使用して検索するときに呼び出しを追加しました
-F
(主に文書化目的です)。grep
grep
出力バッファがいっぱいになるまで何も生成されないように出力をバッファリングします。これは実際には「動作しない」という印象を与えますが、grep
出力バッファをフラッシュするまでは何もしません。これは十分なデータがある場合に行われます。これはパフォーマンスの最適化です。GNU
grep
(およびOpenBSDなどの同じユーティリティの他の実装)は、そのオプションを介して--line-buffered
ラインバッファリングを実行できます。tail -f logfile.log | grep --line-buffered -F 'ERROR' | while read msg; do psql -d testdb -c "insert into t values('$msg')" done
注:現在PostgreSQL(?)インスタンスが実行されていないため、まだテストしていません。