cap waktu sebelum gema


12

Ada cara yang lebih baik untuk membuat cap waktu di depan sebuah echo?

Saat ini saya melakukannya dengan cara ini:

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

Outputnya akan terlihat seperti itu:

10:36 usb device already mounted

Jawaban:


22

Anda bisa melewati echo, dan hanya menaruh pesan di dateperintah. datememungkinkan Anda untuk memasukkan teks ke dalam format string ( +%Rdalam contoh Anda). Sebagai contoh:

date +"%R usb device already mounted"

Anda juga dapat membuangnya ke fungsi shell untuk kenyamanan. Sebagai contoh:

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

echo_time "usb device already mounted"

Ini adalah pembersih jika Anda akan menggunakannya kembali berkali-kali.


6
echo_timeakan melakukan apa yang Anda harapkan, hingga pesan Anda memiliki %tanda masuk di dalamnya. Bukan solusi yang sangat kuat.
derobert

1
@derobert Karena implementasi disembunyikan dalam suatu fungsi, echo_timebisa saja menggunakan tanggal OP + konstruksi gema
Izkata

Saya baru saja mengganti "$ *" dengan "$ @" (untuk membiasakan menggunakan nanti)
Olivier Dulac

bagaimana cara menggunakannya dalam pipa?
erikbwork

6

Berikut ini adalah cara yang lebih kuat dan portabel (POSIX) untuk melakukannya, terutama yang memungkinkan untuk %tetap tidak diproses sebagai argumen:

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

5

Anda dapat membuat variabel untuk 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
Ini bagus karena hanya memanggil tanggal sekali, bukan tiga kali.
evilsoup

2
Ini bagus ketika skrip tidak bertahan lama, tetapi akan memiliki tanggal yang salah ketika akan lebih lama.
TaXXoR

4

Dengan ksh93dan versi terbaru dari bash:

ts_echo() {
  printf '%(%R)T: %s\n' -1 "$*"
}

Dengan zsh:

ts_echo() print -P %T: "$@"

Atau untuk menghindari ekspansi yang cepat di "$@"bagian:

ts_echo() echo ${(%):-%T}: "$@"

Cara hacky untuk versi yang lebih lama dari bash:

ts_echo() (
  PS4="\A"
  set -x; : "$@"
)

Sebenarnya, jika intinya adalah melakukan:

echo "<timestamp>: doing cmd args..."
cmd args...

Anda bisa melakukannya:

ts() (
  PS4='\A: doing '
  set -x; "$@"
)
ts cmd args...

Atau untuk menghindari forking sub shell:

ts() {
  local PS4='\A: doing ' ret
  set -x; "$@"
  { ret=$?; set +x; } 2> /dev/null
  return "$ret"
}

Kemudian:

$ ts echo whatever
14:32: doing echo whatever
whatever

(perhatikan bahwa itu digaungkan di stderr, yang sebenarnya mungkin lebih disukai).


1

Ketika saya melakukan hal-hal seperti ini, saya biasanya ingin semua baris (termasuk keluaran program apa pun) dicentang waktu. Jadi, saya menggunakan sesuatu seperti ini:

#!/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()."] $_"'

Seperti yang ditunjukkan Stephane di bawah ini, masing-masing program dapat buffer output mereka ketika dikirim ke pipa. Tentu saja, buffer ini akan memerah ketika program keluar sehingga paling buruk cap waktu akan muncul ketika program keluar (jika buffer hasilnya dan tidak cukup mencetak untuk mengisi buffer). Namun, echocap waktu semuanya akan akurat.

Sebagai sampel yang dapat dijalankan untuk pengujian:

#!/bin/sh

(
    echo "Doing something"
    sleep 5
    echo "Doing something else..."
    ls /some/file
    sleep 8
    echo "Done."
) 2>&1 | perl -ne 'print "[".localtime()."] $_"'

Keluaran:

[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.

Namun perhatikan bahwa begitu output menuju ke sebuah pipa, aplikasi mulai untuk buffer output mereka, sehingga waktunya mungkin tidak mencerminkan waktu mereka dicetak.
Stéphane Chazelas

2
Saya sarankan memeriksa tsperintah yang merupakan bagian dari moreutils. Ini skrip perl yang serupa, tetapi dengan berbagai opsi untuk format cap waktu, dll.
derobert

@derobert - mengapa Anda tidak menulis bagaimana cara menggunakan ini ts? Sepertinya itu akan menjadi pilihan terbaik di sini.
slm

1

Membuat cap waktu dengan ts

instal alat ts(bagian dari paket moreutils):

sudo apt-get install moreutils

Menambahkan cap waktu ke output:

echo "foo" | ts

keluaran:

Sep 03 14:51:44 foo

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

1
Ini tidak berhasil ketika saya baru mencobanya.
slm

Sama seperti @slm menulis. Anda harus melindungi string dari perintah prematur dan ekspansi variabel.
manatwork
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.