shell 在Bash中像数字时钟一样显示日期和时间

cyej8jka  于 2023-10-23  发布在  Shell
关注(0)|答案(3)|浏览(146)

命令date +'%a %b %e %Y%n%I:%M %p'以以下格式显示日期和时间:

Thu Sep 22 2016
08:02 PM

我在想一种方法,让日期和时间随着时间的变化而更新。我唯一能想到的就是这样做:

#!/bin/bash

while true
do 
    date +'%a %b %e %Y%n%I:%M %p'   
done | awk '!seen[$0]++'

这将产生如下输出:

Thu Sep 22 2016
08:02 PM
08:03 PM
08:04 PM

有没有一种方法可以显示时间的变化,方法是将旧的时间转换为08:02,使08:03在同一行上变化,基本上使日期和时间像普通的数字时钟一样显示?

llew8vvj

llew8vvj1#

要仅在日期更改时更新第一行,每秒更新第二行,请执行以下操作:

while :; do
  # store start date in variable
  printf -v start_day '%(%a %b %e %Y)T'
  day=$start_day

  clear
  echo "$day"
  while sleep 1 && [[ $start_day = $day ]]; do
      printf -v day '%(%a %b %e %Y)T'
      printf '\r%(%I:%M %p)T'
  done
done

使用printf %()T限制了对最新bash 4.x的兼容性,但大大提高了性能(避免了每次我们想要更新时间时都需要启动外部程序)。

f3temu5u

f3temu5u2#

您可以使用tput来移动光标:

date +'%a %b %e %Y%n%I:%M %p'
while sleep 1
do
    tput cuu 2
    date +'%a %b %e %Y%n%I:%M %p'
done
rdlzhqv9

rdlzhqv93#

我还想有一个简单的,单行的实时数字时钟显示,并在我的bash(1) shell 自动更新时,我需要它。下面是我实现的clock()函数的定义,我在~/.bashrc文件中使用了它:

if command -v 'tput' > /dev/null 2>&1; then
        function clock() {
                trap 'tput cnorm; trap - ERR' ERR
                tput civis
                while :; do
                        echo -e 'cr\nel' | tput -S
                        echo -n "$(date)"
                        sleep 1
                done
        }
fi

此函数使用tput(1)实用程序和terminfo(5)终端功能数据库来隐藏光标(civiscursor_invisible功能),将光标移动到行的开头(crcarriage_return功能),并在更新其内容之前将行清除到其结尾(elclr_eol功能)。它还使用tput(1)使光标在返回shell之前再次可见(cnormcursor_normal功能)。
从上面的shell代码中可以看出,这个函数使用了一些shell的trap技巧来实现所需的行为,但它都工作得很好,没有任何问题或副作用。您可以通过在执行此函数之前和之后执行trap -p并按Ctrl + C中断来验证是否不存在临时trap剩余。此函数依赖于tput(1)实用程序,该实用程序通常是不总是安装的ncurses(3X)包的一部分,因此在tput(1)实用程序不存在的情况下,根本不会定义此函数。
当然,您也可以定义date别名来自定义date命令的默认输出格式,或者您可以修改clock()函数来额外指定date命令的格式字符串。例如,下面是我在~/.bashrc文件中使用的别名的定义:

alias date="date '+%A  %B %-d, %Y  %H:%M:%S %Z (%:z)'"

下面是clock()函数的另一个版本,它避免了使用原始版本中的几个bashisms,而是使用了注解中建议的更可移植的结构:

if command -v 'tput' > /dev/null 2>&1; then
        function clock() {
                trap 'tput cnorm; trap - ERR' ERR
                tput civis
                while :; do
                        printf 'cr\nel\n' | tput -S
                        printf '%s' "$(date)"
                        sleep 1
                done
        }
fi

相关问题