2012-04-19 2 views
4

これは本当に簡単なストップウォッチのように考えることができます。私は指定された日付からの経過時間を表示し、毎秒出力を更新するbashスクリプトを一緒にハックしようとしています。ストップウォッチBashスクリプトを作成して、経過時間を常に表示するにはどうすればよいですか?

まず、スクリプト内で、UNIXの日付:Fri Apr 14 14:00:00 EDT 2011を指定します。これはストップウォッチが始まるときです。

、スクリプトを実行したとき、あなたは...

06d:10h:37m:01s

を見ると、数秒後にあなたが見たいと思います...

06d:10h:37m:05s

I毎秒新しい行を印刷しようとしていません。スクリプトは1行の出力しか持たず、1秒ごとに更新する必要があります。明らかに、スクリプトを終了していつでも再起動することができます。起動時間がハードコードされているので、それはまだ間違いありません。

アイデア?

+0

Jordanmnを、私はbashが経過し、「「bashのストップウォッチを」私はグーグルでオンラインで見つけるいくつかのスクリプトを修正しようとしています「時間」および他のそのような照会を含む。 – jerzy

答えて

4

を使用しています。 タイマーは、キーボード割り込みによってメインプロセスが終了した場合に殺される(トラップ)機能(別のプロセス)で実行されます。

... working [hh:mm:ss] 00:07:58 

スニペット:出力は、タイマーを開始してからの経過時間を示して

#=== FUNCTION ================================================================ 
#   NAME: progressIndicatorTime 
# DESCRIPTION: Display a progress indicator with seconds passed. 
# PARAMETERS: [increment] between 1 and 60 [sec], default is 2 [sec] 
#=============================================================================== 
function progressIndicatorTime() 
{ 
    declare default=2          # default increment [sec] 
    declare increment="${1:-$default}"      # 1. parameter or default 
    declare format='\b\b\b\b\b\b\b\b%02d:%02d:%02d'   # time format hh:mm:ss 
    declare timepassed=0 
    declare seconds minutes hours 

    [[ ! "$increment" =~ ^([1-9]|[1-5][0-9]|60)$ ]] && increment=$default 
    printf " ... working [hh:mm:ss] 00:00:00" 
    while : ; do           # infinite loop 
    ((seconds=timepassed%60)) 
    ((minutes=timepassed/60)) 
    ((hours=minutes/60)) 
    ((minutes=minutes%60)) 
    printf "$format" $hours $minutes $seconds 
    sleep $increment || break        # sleep ... 
    ((timepassed+=increment)) 
    done 
} # ---------- end of function progressIndicatorTime ---------- 

progressIndicatorTime &         # run progress indicator 
declare progressIndicatorPid=${!}       # save process ID 
trap "kill $progressIndicatorPid" INT TERM    # trap keyboard interrupt 

# 
# run long command 
# 

kill -s SIGTERM $progressIndicatorPid      # terminate progress indicator 
1

Bash4またはksh93をお持ちの場合は、printf %()Tの構文を使用してstrftimeの形式を印刷できます。次の例は、必要な形式でBash 4を印刷する例です。 Bashの精度は1秒に制限されています。 ksh93は浮動小数点数をサポートしており、何らかの変更が必要です。

#!/usr/bin/env bash 

# To supply a default date/time. To use now as the default, leave empty, or run with a null first arg. 
deftime='Fri Apr 14 14:00:00 EDT 2011' 

if ((${BASH_VERSINFO[0]}${BASH_VERSINFO[1]} >= 42)); then 
    unixTime() { 
     printf ${2+-v "$2"} '%(%s)T' -1 
    } 
else 
    unixTime() { 
     printf ${2+-v "$2"} "$(date '+%s')" 
    } 
fi 

stopWatch() { 
    local timestamp="$(date ${1:+'-d' "$1"} '+%s')" curtime day=$((60*60*24)) hour=$((60**2)) 
    # unixTime -1 timestamp 

    while 
     unixTime -1 curtime 
     ((curtime -= timestamp)) 
     printf '%02dd:%02dh:%02dm:%02ds\r' $((curtime/day)) $(((curtime/hour) % 24)) $(((curtime/60) % 60)) $((curtime % 60)) 
     do sleep 1 
    done 
} 

stopWatch "${1-deftime}" 

また、$SECONDS変数に興味があります。残念ながら、あなたが望むように人間が判読可能な日付を受け入れる便利な方法はありません。かなりの解析作業が必要になります。 dateコマンド(特にGNUの日付)は、それを限られた範囲で行うことができます。

+0

私は、OS X Snow Leopard上でGNU bash、バージョン3.2.48(1)-release(x86_64-apple-darwin10.0)を使用していると指定する必要があります。 – jerzy

+0

./timer.sh:行4:printf: '( ':無効な書式文字です。)このバグを修正する方法はありますか? – jerzy

+0

ここで使用している機能はBash 4.2が必要ですあなたはすべての 'printfs'を日付呼び出しで置き換える必要があります。私はそれがunixTime関数を変更するのと同じくらい簡単だと思います...それをテストする必要があります – ormaaj

2

技術にはいくつかの作業を使用していますが、これを試して与えることができる:

#!/bin/bash 

ref_date='Thu Apr 19 17:07:39 CDT 2012' 
ref_sec=$(date -j -f '%a %b %d %T %Z %Y' "${ref_date}" +%s) 
update_inc=1 

tput clear 
cat <<'EOF' 


      [|]  [|] 
     _-'''''''''''''-_ 
     /    \ 
     |     | 
     |     | 
     |     | 
     \    /
     '-_____________-' 
EOF 

while : 
do 
    ((sec=$(date +%s) - ${ref_sec})) 
    ((day=sec/86400)) 
    ((sec-=day*86400)) 
    ((hour=sec/3600)) 
    ((sec-=hour*3600)) 
    ((min=sec/60)) 
    ((sec-=min*60)) 
    tput cup 6 14 
    printf "%.2id:%.2ih:%.2im:%.2is\r" ${day} ${hour} ${min} ${sec} 
    sleep ${update_inc} 
done 

exit 0 

注最初のdateコマンドの構文はOSXのためのものであることを。 GNU日のために

、私は長時間実行スクリプトに次のコードスニペットを使用しdate --date="${ref_date}" +%s

関連する問題