echo
の前にタイムスタンプを作成するより良い方法がありますか?
現在私はこのようにしています:
#!/bin/sh
if mount | grep -q /mnt/usb; then
echo `date +%R\ ` "usb device already mounted"
else
echo `date +%R\ ` "mounting usb device..."
mount -t msdosfs /dev/da0s1 /mnt/usb
if mount | grep -q /mnt/usb; then
echo `date +%R\ ` "usb device successfully mounted"
fi
fi
出力は次のようになります。
10:36 usb device already mounted
echo
をスキップして、メッセージをdate
コマンドに入れるだけです。 date
を使用すると、フォーマット文字列(+%R
(例では)。例えば:
date +"%R usb device already mounted"
便宜上、それをShell関数にスローすることもできます。例えば:
echo_time() {
date +"%R $*"
}
echo_time "usb device already mounted"
何度も再利用する場合、これはよりクリーンです。
これは、より堅牢で移植可能な(POSIX)方法で、特に%
を引数として未処理のままにできる方法です。
echo_time() {
date +"%H:%M $(printf "%s " "$@" | sed 's/%/%%/g')"
}
date +%R
の変数を作成できます。
#!/bin/sh
T=$(date +%R)
if mount | grep -q /mnt/usb; then
echo "$T usb device already mounted"
else
echo "$T mounting usb device..."
mount -t msdosfs /dev/da0s1 /mnt/usb
if mount | grep -q /mnt/usb; then
echo "$T usb device successfully mounted"
fi
fi
ksh93
およびbash
の最新バージョン:
ts_echo() {
printf '%(%R)T: %s\n' -1 "$*"
}
zsh
の場合:
ts_echo() print -P %T: "$@"
または、"$@"
部分のプロンプト拡張を回避するには:
ts_echo() echo ${(%):-%T}: "$@"
古いバージョンのbash
のハック方法:
ts_echo() (
PS4="\A"
set -x; : "$@"
)
実際には、ポイントがそうする場合:
echo "<timestamp>: doing cmd args..."
cmd args...
あなたがすることができます:
ts() (
PS4='\A: doing '
set -x; "$@"
)
ts cmd args...
または、サブシェルのフォークを回避するには:
ts() {
local PS4='\A: doing ' ret
set -x; "$@"
{ ret=$?; set +x; } 2> /dev/null
return "$ret"
}
次に:
$ ts echo whatever
14:32: doing echo whatever
whatever
(それらはstderrにエコーされることに注意してください。実際にはそれが好ましい場合があります)。
このようなことをするときは、通常、すべての行(プログラム出力を含む)にタイムスタンプを付けたいと思います。したがって、私はこのようなものを使用します:
#!/bin/sh
(
if mount | grep -q /mnt/usb; then
echo "usb device already mounted"
else
echo "mounting usb device..."
mount -t msdosfs /dev/da0s1 /mnt/usb
if mount | grep -q /mnt/usb; then
echo "usb device successfully mounted"
fi
fi
) 2>&1 | Perl -ne 'print "[".localtime()."] $_"'
ステファンが下で指摘するように、個々のプログラムは、パイプに送信されるときに出力をバッファリングする場合があります。もちろん、これらのバッファーはプログラムの終了時にフラッシュされるため、最悪の場合、プログラムが終了したときにタイムスタンプが表示されます(出力がバッファーに入れられ、バッファーを満たすほど印刷されない場合)。ただし、echo
のタイムスタンプはすべて正確です。
テスト用の実行可能なサンプルとして:
#!/bin/sh
(
echo "Doing something"
sleep 5
echo "Doing something else..."
ls /some/file
sleep 8
echo "Done."
) 2>&1 | Perl -ne 'print "[".localtime()."] $_"'
出力:
[Thu Aug 29 07:32:37 2013] Doing something
[Thu Aug 29 07:32:42 2013] Doing something else...
[Thu Aug 29 07:32:42 2013] ls: cannot access /some/file: No such file or directory
[Thu Aug 29 07:32:50 2013] Done.
ts
を使用したタイムスタンプの作成
ツールts
をインストールします(パッケージの一部moreutils)
:
Sudo apt-get install moreutils
タイムスタンプを出力に追加する:
echo "foo" | ts
出力:
Sep 03 14:51:44 foo