web-dev-qa-db-ja.com

エコー前のタイムスタンプ

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
12
TaXXoR

echoをスキップして、メッセージをdateコマンドに入れるだけです。 dateを使用すると、フォーマット文字列(+%R(例では)。例えば:

date +"%R usb device already mounted"

便宜上、それをShell関数にスローすることもできます。例えば:

echo_time() {
    date +"%R $*"
}

echo_time "usb device already mounted"

何度も再利用する場合、これはよりクリーンです。

22
David Baggerman

これは、より堅牢で移植可能な(POSIX)方法で、特に%を引数として未処理のままにできる方法です。

echo_time() {
    date +"%H:%M $(printf "%s " "$@" | sed 's/%/%%/g')"
}
6
jlliagre

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
5
Radu Rădeanu

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にエコーされることに注意してください。実際にはそれが好ましい場合があります)。

4

このようなことをするときは、通常、すべての行(プログラム出力を含む)にタイムスタンプを付けたいと思います。したがって、私はこのようなものを使用します:

#!/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.
1
Dean Serenevy

tsを使用したタイムスタンプの作成

ツールtsをインストールします(パッケージの一部moreutils)

Sudo apt-get install moreutils

タイムスタンプを出力に追加する:

echo "foo" | ts

出力:

Sep 03 14:51:44 foo
1
TaXXoR