支持GNU或Solaris 11 sleep
参数(一个或多个<double>[smhd]
持续时间,因此也可以与仅支持一个十进制整数的传统实现一起使用(例如,在FreeBSD上),但不能接受那些接受更复杂的参数(例如ISO-8601持续时间)的实现。使用etime
代替,etimes
因为那样更便于移植(标准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'
}
(该s/\?//g
是摆脱的?
字符procps
“ ps
用途作为替代控制字符。如果没有它,就无法解析sleep $'\r1d'
或sleep $'\t1d'
...不幸的是,在某些地区,包括C
语言环境,它使用.
的不是?
。没有太多我们可以做在这种情况下,因为没有办法知道一个\t5d
从.5d
(半天))。
将pid作为参数传递。
这还假定argv[0]
传递给的sleep
不包含空格,并且参数的数量足够小,不会被截断ps
。
例子:
$ sleep infinity & remaining_sleep_time "$!"
Inf
$ sleep 0xffp-6d &
$ remaining_sleep_time "$!"
344249
$ sleep 1m 1m 1m 1m 1m & remaining_sleep_time "$!"
300
对于[[[ddd-]HH:]MM:]SS
输出而不是秒数,请替换为print $t
:
$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;
sh -c 'sleep 1; sleep 2'
许多sh
实现中,执行sh
和稍后执行sleep 2
(1秒后)的过程都是相同的。