如何从linux下面的命令中获取up
的值?
# w
01:16:08 up 20:29, 1 user, load average: 0.50, 0.34, 0.30
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 00:57 0.00s 0.11s 0.02s w
# w | grep up
01:16:17 up 20:29, 1 user, load average: 0.42, 0.33, 0.29
答案 0 :(得分:4)
在 Linux 上,通过/proc/uptime
的第一个字段获取正常运行时间<分数秒 的最简单方法(见man proc
):
$ cut -d ' ' -f1 /proc/uptime
350735.47
使用w
格式设置与uptime
和awk
相同的方式格式化该数字:
$ awk '{s=int($1);d=int(s/86400);h=int(s % 86400/3600);m=int(s % 3600 / 60);
printf "%d days, %02d:%02d\n", d, h, m}' /proc/uptime
4 days, 01:25 # 4 days, 1 hour, and 25 minutes
按要求回答问题 - 解析w
的输出(或uptime
,其输出与{{1}相同第一个输出行,其中包含所有感兴趣的信息),也适用于macOS / BSD ,粒度为积分秒:
w
解决方案:
perl
是一个Bash流程替换,提供<(uptime)
的输出作为uptime
命令的输入 - 见底部。
perl
这假设$ perl -nle 'print for / up +((?:\d+ days?, +)?[^,]+)/' <(uptime)
4 days, 01:25
是每个显示的最大单位。
days
告诉Perl逐行处理输入,默认情况下不打印任何输出(perl -nle
),在输入时自动从每个输入行剥离尾随换行符,并自动追加一个输出(-n
); -l
告诉Perl将下一个参数视为要处理的脚本(表达式)。
-e
告诉Perl输出正则表达式print for /.../
内捕获的每个捕获组(...)
。
/.../
与文字up +
匹配,前面有(至少)一个空格,后跟一个或多个空格(up
) +
是一个非捕获子表达式 - 由于(?:\d+ days?, +)?
- 匹配:
?:
)\d+
,后面跟着文字day
(s
)s?
使整个子表达式可选,因为可能存在或不存在数天的部分。 ?
匹配1个或多个([^,]+
)后续字符,但不包括文字+
(,
) - 这是{{ 1}} part。
整个捕获组 - 外部[^,]
因此捕获整个正常运行时表达式 - 无论是仅由hh:mm
组成还是由(...)
组成 - 并打印出来。
hh:mm
是Bash process substitution (<(...)
)
松散地说,将<n> day/s>
的输出呈现为<(uptime)
可以通过标准输入读取的(临时的,自我删除的)文件。
答案 1 :(得分:2)
使用gnu sed这样的东西:
$ w |head -n1
02:06:19 up 3:42, 1 user, load average: 0.01, 0.05, 0.13
$ w |sed -r '1 s/.*up *(.*),.*user.*/\1/g;q'
3:42
$ echo "18:35:23 up 18 days, 9:08, 6 users, load average: 0.09, 0.31, 0.41" \
|sed -r '1 s/.*up *(.*),.*user.*/\1/g;q'
18 days, 9:08
答案 2 :(得分:0)
鉴于正常运行时间的格式取决于它是否少于或超过24小时,我能想到的最好是双awk
:
$ w
18:35:23 up 18 days, 9:08, 6 users,...
$ w | awk -F 'user|up ' 'NF > 1 {print $2}' \
| awk -F ',' '{for(i = 1; i < NF; i++) {printf("%s ",$i)}} END{print ""}'
18 days 9:08