显示 Linux 安装时间(以天为单位)的脚本

显示 Linux 安装时间(以天为单位)的脚本

我想创建一个名为的命令Age来调用此脚本:

From=$(stat / | grep "Birth" | sed 's/Birth: //g' | cut -b 2-11)
echo $From
Now=$(date)
echo $Now

但是,我一直在减去这两个日期。

我怎样才能减去它们并确保它不会像2022-05-07with那样与日期时间混淆2022-07-05?我的意思是,是哪一个月,哪一天是哪一天?

我认为我应该更改命令的格式stat以使其更具描述性,以防止这种混乱,然后确保两个日期的格式相同,然后减去它们。但我找不到如何做。

答案1

这个答案是错误的!!!应根据秒数手动计算差异。用命令显示date只显示月份,当天的天数,距离 如此多的秒数1970-01-01


我会这样做:

#!/bin/bash

d1=$(date -d "$(stat / | grep "Birth" | sed 's/Birth: //g')" +%s)
d2=$(date +%s)
date -d "@$(($d2 - $d1))" +'%m months, %d days, %H hours'

在几秒钟内获得两次。减去它们并以您选择的格式显示它们。在本例中,它以月、日和小时为单位。您可以根据自己的喜好更改它。尝试man date看看您有哪些输出格式选项。

关于日期格式 YYYY-MM-DD 的混淆,我从未见过计算机将其错误地解释为 YYYY-DD-MM。


根据 muru 的评论添加(oneliner):

date -d "@$(($(date +%s) - $(stat / --format %W)))" +'%m months, %d days, %H hours'

在@Saeed Neamati 评论后添加。以下答案提供了更好的解决方案。他们仍然不是100%正确。

第一个选项 如果计算差异,然后将该差异添加到 1970-01-01,则可以显示与 1970-01-01 的年、月和日差异。由于月份长度不同且存在闰年,结果并不准确:

seconds=$(date -d "@$(($(date +%s) - $(stat / --format %W)))" +%s)
years=$(($(date -d @$seconds +%Y) - 1970))
months=$(($(date -d @$seconds +%m) - 1))
days=$(($(date -d @$seconds +%d)))
echo $years years, $months months, $days days

第二个选择 另一种方法是获取两个日期并计算它们之间的差异。天数可能不正确,因为并非所有月份都是 31 天长:

d1_year=$(date -d @$(stat / --format %W) +%Y)
d1_month=$(date -d @$(stat / --format %W) +%-m)
d1_day=$(date -d @$(stat / --format %W) +%-d)

d2_year=$(date +%Y)
d2_month=$(date +%-m)
d2_day=$(date +%-d)

years=$(($d2_year - $d1_year))
months=$(($d2_month - $d1_month))
if (( $months < 0 )); then
    months=$(($months + 12))
    years=$(($years - 1))
fi
days=$((d2_day - $d1_day))
if (( $days < 0 )); then
    days=$(($days + 31))
    months=$((months -1))
fi

echo $years years, $months months, $days days

答案2

2022-05-07,与 05/07/22 或 07/05/2022 相反,是明确的标准日期格式,始终为 YYYY-MM-DD。但是,在这里,您不需要解析日历日期时间,您可以获取自纪元以来的秒数原始数据。

与 GNU stat(最近足够并使用最近的 glibc 和 Linux 内核,因此它报告诞生时间)和ddiff来自dateutilsdateutils.ddiff在 Debian 及其衍生版本中)的命令:

ddiff -i %s -f %d "$(stat -c%W /)" now

或者近似计算一天为 86400 秒(它们是 86400 Unix 秒,但由于某些时区的 DST,计算在极少数情况下可能会偏差一天):

echo "$(( ($(date +%s) - $(stat -c%W /)) / 86400 ))"

使用 zsh 之后zmodload zsh/datetime 或使用最新版本的bash,$(date +%s)可以替换为$EPOCHSECONDS.

ts来自 moreutils,with -r,可以解析时间戳并将其转换为某种61d25m ago/166d7h ago格式。它可以识别多种时间戳格式,包括 ISO-8600 格式,因此您需要stat稍微转换 的输出,并获取 UTC 时间,因为我认为不会ts解释时区部分:

TZ=UTC0 stat -c%w / |
  sed 's/ /T/;s/ .*/Z/' |
  ts -r

或者使用 GNUfind而不是statwithTZ=UTC0 find / -prune -printf '%BFT%BTZ\n'从一开始就以正确的格式获取时间戳(同样,需要最新版本的 findutils、glibc、Linux)。

相关内容