「睡眠」時間がどれくらい残っているかを確認する方法は?

「睡眠」時間がどれくらい残っているかを確認する方法は?

私は持っています:

sleep 210m && for i in $(seq 1 5); do echo -e '\a'; sleep 0.5; done 

私が何をすべきかを教えてくれるシンプルで実用的なタイマーで動作します。sleep 210mPID 25347です。

私は睡眠がどれくらい残ったかを調べようとしました。最初の睡眠時間(210分)を追加すると、私が思いついた最高の睡眠時間は次のようになります。

$ echo "210 60 * $(ps -o etimes= 25347) - 60 ~ r n [:] P p" | dc
78:11

(説明:最初のビットは元の睡眠の秒を計算します。そのビットは睡眠が$(ps…)始まってからの時間を秒単位で取得し、残りのビットはそれを減算して分と秒単位で表示します。)

私はこれが一般的に役に立つと思います。より良い方法はありますか?それとも、少なくとも睡眠時間を分析する賢明な方法はありますかps -o args

答え1

GNUまたはSolaris 11sleepパラメータ(1つ以上の<double>[smhd]期間)がサポートされているため、10進整数のみをサポートする従来の実装(FreeBSDなど)でも機能しますが、より複雑なパラメータを許可する実装では機能しません。ISO-8601期間)。移植性が高いので、etime代わりに使用してください(標準Unix)。etimes

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制御文字の代わりに使用される ' 文字を削除するためのものです?。これがなければ構文解析されないか... 残念ながらロケールを含む一部のロケールでは代わりに使用されます。 この場合にはできることはありません。 a(半日)を区別する方法はありません。procpspssleep $'\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;

答え2

これは興味深い質問のようです。 thrigはperlオプションを扱うので、同様のことをするbashスクリプトがあります。エラーチェックが不十分です(sleepコマンドに有効なPIDを渡すとします)。同じ構文を処理します。GNU coreutils スリープモード実際には次のようになります。

  • s | m | h | dは、秒/分/時間/日のサフィックスを表します。
  • 複数時間パラメータの追加

#!/usr/bin/env bash

# input: PID of a sleep command
# output: seconds left in the sleep command

function parse_it_like_its_sleep {
  # $1 = one sleep parameter
  # print out the seconds it translates to

  mult=1
  [[ $1 =~ ([0-9][0-9]*)(s|m|h|d) ]] && {
    n=${BASH_REMATCH[1]}
    suffix=${BASH_REMATCH[2]}
  } || {
    n=$1
  }
  case $suffix in
    # no change for 's'
    (m) mult=60;;
    (h) mult=$((60 * 60));;
    (d) mult=$((60 * 60 * 24));;
  esac
  printf %d $((n * mult))
}

# TODO - some sanity-checking for $1
set -- $(ps -o etimes=,args= $1)
[[ $2 = "sleep" ]] || exit 1
elapsed=$1
shift 2
total=0
for arg
do
  # TODO - sanity-check $arg
  s=$(parse_it_like_its_sleep $arg)
  total=$((total + s))
done
printf "%d seconds left\n" $((total - elapsed))

答え3

使用できる簡単なソリューションを探している場合は、次のようにps aux表示されます。スタート時間。 しかし、正確な値を実行するのではなく、高速な近似のためにのみ使用したいかもしれません。

この例では、開始時間は15:47です。それで、眠りは15時57分頃に終わります。

ここに画像の説明を入力してください。

答え4

tqdm Pythonモジュールを使用すると簡単です。

素晴らしいビジュアルプログレスバーを表示し、Unixパイプとして使用できます。

https://pypi.python.org/pypi/tqdm

次のPythonコードスニペットは100秒を数えます。

import time
from tqdm import tqdm
for i in tqdm(range(100)):
    time.sleep(1)

55%|███████████ | 55/100 [00:55<00:45, 1.00秒/it]

関連情報