ประทับเวลาก่อนเสียงสะท้อน


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

1
@derobert เนื่องจากการใช้งานถูกซ่อนอยู่ในฟังก์ชั่นecho_timeเพียงแค่สามารถใช้วันที่ของ OP + สร้างก้อง
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
นี่เป็นสิ่งที่ดีเพราะจะเรียกวันที่ครั้งเดียวมากกว่าสามครั้ง
evilsoup

2
นี่เป็นสิ่งที่ดีเมื่อสคริปต์ไม่นาน แต่มันจะมีวันที่ไม่ถูกต้องเมื่อมันจะนานขึ้น
TaXXoR

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ประทับเวลาทั้งหมดจะถูกต้อง

เป็นตัวอย่าง runnable สำหรับการทดสอบ:

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

อย่างไรก็ตามโปรดทราบว่าเมื่อเอาต์พุตกำลังไปยังไพพ์แอปพลิเคชันจะเริ่มบัฟเฟอร์เอาต์พุตดังนั้นเวลาอาจไม่สะท้อนเวลาที่พิมพ์
Stéphane Chazelas

2
ฉันขอแนะนำให้ตรวจสอบtsคำสั่งซึ่งเป็นส่วนหนึ่งของ moreutils สคริปต์คล้าย 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 เขียน คุณต้องป้องกันสตริงจากคำสั่งก่อนวัยและการขยายตัวแปร
จัดการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.