dấu thời gian trước một tiếng vang


12

Tồn tại một cách đẹp hơn để tạo dấu thời gian ở phía trước echo?

Hiện tại tôi làm theo cách này:

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

Đầu ra sẽ trông giống như thế:

10:36 usb device already mounted

Câu trả lời:


22

Bạn có thể bỏ qua echovà chỉ cần đặt thông báo trong datelệnh. datecho phép bạn chèn văn bản vào chuỗi định dạng ( +%Rtrong ví dụ của bạn). Ví dụ:

date +"%R usb device already mounted"

Bạn cũng có thể ném nó vào một hàm shell để thuận tiện. Ví dụ:

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

echo_time "usb device already mounted"

Đây là một trình dọn dẹp nếu bạn sẽ sử dụng lại nhiều lần.


6
echo_timesẽ làm những gì bạn mong đợi, cho đến khi tin nhắn của bạn có một %dấu hiệu trong đó. Không phải là một giải pháp rất mạnh mẽ.
derobert

1
@derobert Vì việc triển khai bị ẩn trong một hàm, echo_timenên chỉ có thể sử dụng cấu trúc ngày + tiếng vang của OP
Izkata

Tôi chỉ cần thay đổi "$ *" bằng "$ @" (để có thói quen sử dụng sau này)
Olivier Dulac

Làm thế nào để sử dụng nó trong một đường ống?
erikbwork

6

Đây là một cách mạnh mẽ và di động hơn (POSIX) để làm điều đó, đặc biệt là một cách cho phép %không bị xử lý như một đối số:

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

5

Bạn có thể tạo một biến cho 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
Điều này là tốt bởi vì nó chỉ gọi ngày một lần, chứ không phải ba lần.
evilsoup

2
Điều này là tốt khi kịch bản không kéo dài, nhưng nó sẽ có ngày sai khi nó sẽ dài hơn.
TaXXoR

4

Với ksh93và các phiên bản gần đây của bash:

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

Với zsh:

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

Hoặc để tránh mở rộng nhanh chóng trong "$@"phần:

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

Một cách hacky cho các phiên bản cũ hơn của bash:

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

Trên thực tế, nếu quan điểm là phải làm:

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

Bạn có thể làm:

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

Hoặc để tránh đổ vỏ phụ:

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

Sau đó:

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

(lưu ý rằng những cái đó được lặp lại trên stderr, mà thực sự có thể thích hợp hơn).


1

Khi tôi làm những việc như thế này, tôi thường muốn tất cả các dòng (bao gồm bất kỳ đầu ra chương trình nào) được đánh dấu thời gian. Vì vậy, tôi sẽ sử dụng một cái gì đó như thế này:

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

Như Stephane chỉ ra bên dưới, các chương trình riêng lẻ có thể đệm đầu ra của chúng khi được gửi đến một đường ống. Tất nhiên, các bộ đệm này sẽ bị xóa khi chương trình thoát, vì vậy tệ nhất là các dấu thời gian sẽ hiển thị khi chương trình thoát (nếu nó đệm đầu ra của nó và không in đủ để lấp đầy bộ đệm). Tuy nhiên, echotất cả các dấu thời gian sẽ chính xác.

Là một mẫu có thể chạy được để thử nghiệm:

#!/bin/sh

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

Đầu ra:

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

Tuy nhiên, lưu ý rằng một khi đầu ra đi vào một đường ống, các ứng dụng bắt đầu đệm đầu ra của chúng, vì vậy thời gian có thể không phản ánh thời gian chúng được in.
Stéphane Chazelas

2
Tôi đề nghị kiểm tra tslệnh là một phần của moreutils. Đây là một tập lệnh perl tương tự, nhưng với các tùy chọn khác nhau cho định dạng dấu thời gian, v.v.
derobert

@derobert - tại sao bạn không viết ra cách sử dụng ts? Có vẻ như nó sẽ là lựa chọn tốt nhất ở đây.
slm

1

Tạo dấu thời gian với ts

cài đặt công cụ ts(một phần của gói moreutils):

sudo apt-get install moreutils

Thêm dấu thời gian vào đầu ra:

echo "foo" | ts

đầu ra:

Sep 03 14:51:44 foo

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

1
Điều này đã không làm việc khi tôi chỉ thử nó.
slm

Giống như @slm đã viết. Bạn phải bảo vệ chuỗi khỏi lệnh sớm và mở rộng biến.
manatwork
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.