2016-09-21 3 views
0

ログファイルの各エントリにタイムスタンプを付加するこのbashスクリプトを持っていますが、それをkornシェル構文に変換することに固執しています。私はコーンシェルはサブシェルが好きではないと読んでいます。私は機能を利用しようとしましたが、うまく機能しませんでした。特に、exec行全体をkorn構文に変換しようとしました。誰かが見て、私を助けてくれますか?kshのプロセス置換(stdoutを変更する)

#!/usr/bin/bash 

exec > >(
    while read line ; do 
     echo "$(date '+%Y%m%d %H:%M:%S') ${line}" 
    done > n.log 
) 2>&1 

echo 'first line; should have an initial timestamp' 
sleep 2 
echo 'printed two seconds later, should have a timestamp with a comparable offset' 
+0

ここをクリックしてください... http://unix.stackexchange.com/a/26797 –

+0

** ** ** ** kshの実装はどれですか?これは、本物のDavid Korn ksh93とmkshまたはpdkshとの非常に異なる回答になるでしょう。 –

+1

ところで、提供されるbashコードは本当に**本当に非効率的です( '$(date)'はサブシェルを起動し、そのサブシェルで外部サブプロセスを実行します。出力)。最新の(4.1?4.2?)バージョンのbashをprintfに組み込まれたネイティブstrftimeサポートとともに使用していた場合、このフィルタのパフォーマンスオーバーヘッドを大幅に削減できます。 –

答えて

1

POSIX準拠のシェルで動作する移植可能なものは、名前付きFIFOを使用することです。

最近のbashでも利用できるksh拡張子(printf %()T)は、サブシェル内にdateを起動する必要を避けるために使用されています。

mkfifo log.fifo 
(while IFS= read -r line; do 
    printf '%(%Y%m%d %H:%M:%S)T ' 
    printf '%s\n' "$line" 
done >n.log <log.fifo) & 
exec >log.fifo 
+0

'bash'と' ksh'(少なくともOS Xに同梱されているバージョン)は、現在の日付と時刻を出力するために第2引数を全く省略することができます。 – chepner

+0

@Charlesご協力いただきありがとうございます。今はbashとkshの両方で動作するので、私は異なるシェルのために2つのコードは必要ありません。 – Ben

+0

@chepner、bash 4.4.0、 'printf '%(%Y)T \ n' '''は私に '1969'を与えます。したがって、同じ形式の文字列でパラメータ化されたコンポーネントが必要な場合は、そのルートを実行することは現実的ではありません...私は2つの別々の 'printf'呼び出しを使用することができます。 –

0

チャールズの優れた答えにはほとんどの拡張:出力変更のため、メインの機能コードの別々の機能を作成することにより、 それがより明確ください。名前付きパイプなしでは、完了後にクリーンアップするものはありません。

print_with_timestamps() { 
    (while IFS= read -r line; do 
    printf '%(%Y%m%d %H:%M:%S)T ' 
    printf '%s\n' "$line" 
    done 
) > n.log 2>&1 
} 

main() { 
echo 'first line; should have an initial timestamp' 
sleep 2 
echo 'printed two seconds later, should have a timestamp with a comparable offset' 
} 

main | print_with_timestamps 
関連する問題