Supporting GNU or Solaris 11 sleep
arguments (one or more <double>[smhd]
durations, so would also work with traditional implementations that support only one decimal integer number (like on FreeBSD), but not with those accepting more complex arguments like ISO-8601 durations). Using etime
instead of etimes
as that's more portable (standard Unix).
remaining_sleep_time() { # arg: pid
ps -o etime= -o args= -p "$1" | perl -MPOSIX -lane '
%map = qw(d 86400 h 3600 m 60 s 1);
$F[0] =~ /(\d+-)?(\d+:)?(\d+):(\d+)/;
$t = -($4+60*($3+60*($2+24*$1)));
for (@F[2..$#F]) {
s/\?//g;
($n, $p) = strtod($_);
$n *= $map{substr($_, -$p)} if $p;
$t += $n
}
print $t'
}
(the s/\?//g
is to get rid of the ?
characters that procps
' ps
uses as replacement for control characters. Without it, it would fail to parse sleep $'\r1d'
or sleep $'\t1d'
... Unfortunately, in some locales, including the C
locale, it uses .
instead of ?
. Not much we can do in that case as there's no way to tell a \t5d
from a .5d
(half day)).
Pass the pid as argument.
That also assumes the argv[0]
passed to sleep
doesn't contain blanks and that the number of arguments is small enough that it's not truncated by ps
.
Examples:
$ sleep infinity & remaining_sleep_time "$!"
Inf
$ sleep 0xffp-6d &
$ remaining_sleep_time "$!"
344249
$ sleep 1m 1m 1m 1m 1m & remaining_sleep_time "$!"
300
For a [[[ddd-]HH:]MM:]SS
output instead of just the number of seconds, replace the print $t
with:
$output = "";
for ([60,"%02d\n"],[60,"%02d:"],[24,"%02d:"],[inf,"%d-"]) {
last unless $t;
$output = sprintf($_->[1], $t % $_->[0]) . $output;
$t = int($t / $_->[0])
}
printf "%s", $output;
You're comparing apples and oranges.
ps
will list the processes running. You're then getting the count of unique process-owning user ids.
uptime
will report the users logged on. By using utmp. More details at https://github.com/coreutils/coreutils/blob/master/src/uptime.c#L177
So, comparison of output, highlighting this, below.
# uptime
16:52:37 up 30 days, 23:32, 1 user, load average: 0.04, 0.04, 0.05
# w
16:57:33 up 30 days, 23:37, 1 user, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
steve pts/0 cpc79909-stkp12- 16:50 5.00s 0.07s 0.28s sshd: steve [priv]
#
# ps -Af | cut -f1 -d' ' | sort | uniq | wc -l
7
# ps -Af | cut -f1 -d' ' | sort | uniq
chrony
dbus
polkitd
postfix
root
steve
UID
#
Best Answer
The following commands work with Python 2.7.15rc1 on my Mint 19.
They will display the uptime excluding sleep time.
The above shows the time in seconds with a decimal.
The above shows the time in seconds with no decimal.
The above shows the time in minutes.
The above shows the time in hours and minutes.
The above shows the time in hours, minutes, and seconds.
The above shows the time in days, hours, and minutes.
I have used
CLOCK_MONOTONIC
andAwk
to create a script that will calculate the total time if my Mint has been started more than once on the same date. TheAwk
command can even be used to calculate the total time in one week/month/year.