17

我在 bash 中使用 uptime 来获取机器的当前运行时间。我需要获取时间并显示 2 天 12 小时 23 分钟等格式。

4

8 回答 8

36

uptime产生的输出如下所示:

$ uptime
 12:49:10 up 25 days, 21:30, 28 users,  load average: 0.50, 0.66, 0.52

要将其转换为您的格式:

$ uptime | awk -F'( |,|:)+' '{print $6,$7",",$8,"hours,",$9,"minutes."}'
25 days, 21 hours, 34 minutes.

这个怎么运作

  • -F'( |,|:)+'

    awk 将其输入划分为多个字段。这告诉 awk 使用空格、逗号或冒号中的一个或多个的任意组合作为字段分隔符。

  • print $6,$7",",$8,"hours,",$9,"minutes."

    这告诉 awk 打印第六个字段和第七个字段(用空格分隔),后跟逗号,第 8 个字段,字符串hours,第九个字段,最后是字符串minutes.

使用 sed 处理正常运行时间较短的计算机

从重新启动开始,我的uptime输出如下:

 03:14:20 up 1 min,  2 users,  load average: 2.28, 1.29, 0.50
 04:12:29 up 59 min,  5 users,  load average: 0.06, 0.08, 0.48
 05:14:09 up  2:01,  5 users,  load average: 0.13, 0.10, 0.45
 03:13:19 up 1 day, 0 min,  8 users,  load average: 0.01, 0.04, 0.05
 04:13:19 up 1 day,  1:00,  8 users,  load average: 0.02, 0.05, 0.21
 12:49:10 up 25 days, 21:30, 28 users,  load average: 0.50, 0.66, 0.52

以下sed命令处理这些格式:

uptime | sed -E 's/^[^,]*up *//; s/, *[[:digit:]]* users.*//; s/min/minutes/; s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/' 

使用上述时间,这会产生:

1 minutes
59 minutes
2 hours, 1 minutes
1 day, 0 minutes
1 day,  1 hours, 0 minutes
25 days, 21 hours, 30 minutes

这个怎么运作

  • -E打开扩展的正则表达式语法。(在较旧的 GNU seds 上,使用-r代替-E

  • s/^[^,]*up *//

    此替换命令删除所有文本,直到up.

  • s/, *[[:digit:]]* users.*//

    此替换命令会删除用户计数及其后面的所有文本。

  • s/min/minutes/

    这替换minminutes.

  • s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/'

    如果该行包含 hh:mm 格式的时间,这会将小时与分钟分开并将其替换为hh hours, mm minutes.

使用 awk 处理正常运行时间短的计算机

uptime | awk -F'( |,|:)+' '{d=h=m=0; if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'

在与上述相同的测试用例中,这会产生:

0 days, 0 hours, 1 minutes.
0 days, 0 hours, 59 minutes.
0 days, 2 hours, 1 minutes.
1 days, 0 hours, 0 minutes.
1 days, 1 hours, 0 minutes.
25 days, 21 hours, 30 minutes.

对于那些喜欢分散在多行上的 awk 代码的人:

uptime | awk -F'( |,|:)+' '{
    d=h=m=0;
    if ($7=="min")
        m=$6;
    else {
        if ($7~/^day/) { d=$6; h=$8; m=$9}
        else {h=$6;m=$7}
        }
    }
    {
        print d+0,"days,",h+0,"hours,",m+0,"minutes."
    }'
于 2015-02-05T20:53:54.987 回答
23

只是 vor 完整性......是关于什么的:

$ uptime -p
up 2 weeks, 3 days, 14 hours, 27 minutes
于 2015-09-23T19:41:25.130 回答
6

解决方案:为了在几秒钟内获得 linux 正常运行时间,转到 bash 并键入cat /proc/uptime.Parse 第一个数字并根据您的要求进行转换。

来自 RedHat文档

该文件包含详细说明系统自上次重新启动以来运行了多长时间的信息。的输出/proc/uptime非常小:

350735.47 234388.90

一个数字是系统已启动的总秒数。

第二数字是机器空闲的时间,以秒为单位。

于 2020-07-14T13:55:54.313 回答
3

uptime -p我为支持较新的 linux 的系统和不支持的系统(如 Mac OS X)制作了一个通用的 shell 脚本。

#!/bin/sh

uptime -p >/dev/null 2>&1

if [ "$?" -eq 0 ]; then
  # Supports most Linux distro
  # when the machine is up for less than '0' minutes then
  # 'uptime -p' returns ONLY 'up', so we need to set a default value
  UP_SET_OR_EMPTY=$(uptime -p | awk -F 'up ' '{print $2}')
  UP=${UP_SET_OR_EMPTY:-'less than a minute'}
else
  # Supports Mac OS X, Debian 7, etc
  UP=$(uptime | sed -E 's/^[^,]*up *//; s/mins/minutes/; s/hrs?/hours/;
  s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/;
  s/^1 hours/1 hour/; s/ 1 hours/ 1 hour/;
  s/min,/minutes,/; s/ 0 minutes,/ less than a minute,/; s/ 1 minutes/ 1 minute/;
  s/  / /; s/, *[[:digit:]]* users?.*//')
fi

echo "up $UP"

要旨

用我自己的自定义引用了 John1024 的答案。

于 2019-11-10T12:44:18.997 回答
2

为了这:

  • 0天,0小时,1分钟。
  • 0 天 0 小时 59 分钟。
  • 0 天 2 小时 1 分钟。
  • 1 天 0 小时 0 分钟。
  • 1天1小时0分钟。
  • 25 天 21 小时 30 分钟

更简单的是:
uptime -p | cut -d " " -f2-

于 2018-04-01T16:37:11.313 回答
1

为了多样化,这里有一个 sed 的例子:

我的原始输出:

$ uptime
15:44:56 up 3 days, 22:58,  7 users,  load average: 0.48, 0.40, 0.31

转换后的输出:

$uptime|sed 's/.*\([0-9]\+ days\), \([0-9]\+\):\([0-9]\+\).*/\1, \2 hours, \3 minutes./'
3 days, 22 hours, 58 minutes.
于 2015-02-06T07:47:55.377 回答
0

这个答案对于 OS X 中的交付非常具体uptime,但考虑到任何输出情况。

#!/bin/bash

INFO=`uptime`
echo $INFO | awk -F'[ ,:\t\n]+' '{
        msg = "↑ "
        if ($5 == "day" || $5 == "days") {      # up for a day or more
            msg = msg $4 " " $5 ", "

            n = $6
            o = $7
        } else {
            n = $4
            o = $5
        }

        if (int(o) == 0) {                      # words evaluate to zero
            msg = msg int(n)" "o
        } else {                                # hh:mm format
            msg = msg int(n)" hr"
            if (n > 1) { msg = msg "s" }

            msg = msg ", " int(o) " min"
            if (o > 1) { msg = msg "s" }
        }

        print "[", msg, "]"
    }'

一些可能的输出示例:

22:49 up 24 secs, 2 users, load averages: 8.37 2.09 0.76
[ ↑ 24 secs ]

22:50 up 1 min, 2 users, load averages: 5.59 2.39 0.95
[ ↑ 1 min ]

23:39 up 51 mins, 3 users, load averages: 2.18 1.94 1.74
[ ↑ 51 mins ]

23:54 up 1:06, 3 users, load averages: 3.67 2.57 2.07
[ ↑ 1 hr, 6 mins ]

16:20 up 120 days, 10:46, 3 users, load averages: 1.21 2.88 0.80
[ ↑ 120 days, 10 hrs, 46 mins ]
于 2016-02-01T03:51:32.410 回答
0
uptime_minutes() {
  set `uptime -p`
  local minutes=0

  shift
  while [ -n "$1" ]; do
    case $2 in
      day*)
        ((minutes+=$1*1440))
        ;;
      hour*)
        ((minutes+=$1*60))
        ;;
      minute*)
        ((minutes+=$1))
        ;;
    esac
   shift
   shift
  done

  echo $minutes
}
于 2020-04-15T15:51:22.667 回答