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


12

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

回答:


22

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

date +"%R usb device already mounted"

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

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

echo_time "usb device already mounted"

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


6
echo_timeメッセージに%サインが入るまで、あなたが期待することをします。非常に堅牢なソリューションではありません。
derobert 2013

1
@derobert実装は関数内に隠されているecho_timeため、OPのdate + echoコンストラクトを使用できます
Izkata

私は "$ *"を "$ @"に変更するだけです(後で使用する習慣をつけるため)
Olivier Dulac

パイプでそれを使用する方法?
erikbwork

6

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

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

5

次の変数を作成できます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

3
これは、3回ではなく1回だけ日付を呼び出すので、便利です。
evilsoup 2013

2
これは、スクリプトが長く続かない場合に便利ですが、長くなると誤った日付になります。
TaXXoR 2013

4

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


1

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

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

ただし、出力がパイプに送られると、アプリケーションは出力のバッファリングを開始するため、タイミングが出力された時刻を反映していない可能性があることに注意してください。
ステファンChazelas

2
tsmoreutilsの一部であるコマンドをチェックアウトすることをお勧めします。しかし、タイムスタンプの書式などのためのさまざまなオプションとの類似したperlスクリプト
derobert

@derobert-これを使用してこれを行う方法を書いてみませんtsか?ここでそれが最良の選択肢になるようです。
slm

1

タイムスタンプを作成する ts

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

sudo apt-get install moreutils

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

echo "foo" | ts

出力:

Sep 03 14:51:44 foo

-1
alias echo="d=$(date +%Y-%m-%d); echo $d "
echo hola

1
試してみたところ、うまくいきませんでした。
slm

@slmが書いたように。文字列を時期尚早なコマンドや変数の展開から保護する必要があります。
manatwork 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.