私は現在、これを使用してbashプロンプトに現在の時刻を表示しています。
PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]
20:42:23 ~>
前回のプロンプトからの経過時間を表示することはできますか?といった:
00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>
私は現在、これを使用してbashプロンプトに現在の時刻を表示しています。
PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]
20:42:23 ~>
前回のプロンプトからの経過時間を表示することはできますか?といった:
00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>
回答:
これを行う1つの方法は、bashのPROMPT_COMMAND機能を使用して、PS1を変更するコードを実行することです。以下の関数は、私の最初のサブミッションの更新版です。これは、2つ少ない環境変数を使用し、既存の変数を壊さないようにするために、それらの前に「_PS1_」を付けます。
prompt_command() {
_PS1_now=$(date +%s)
PS1=$( printf "\[\e[0;32m\]%02d:%02d:%02d \W>\[\e[1;37m\] " \
$(( ( _PS1_now - _PS1_lastcmd ) / 3600)) \
$(( (( _PS1_now - _PS1_lastcmd ) % 3600) / 60 )) \
$(( ( _PS1_now - _PS1_lastcmd ) % 60)) \
)
_PS1_lastcmd=$_PS1_now
}
PROMPT_COMMAND='prompt_command'
_PS1_lastcmd=$(date +%s)
それを.bash_profileに入れて、物事を始めましょう。
sleep
パラメータをプロンプトパラメータと一致させるには、かなりすばやく入力する必要があることに注意してください。時間は、コマンドの入力にかかる時間を含め、実際にはプロンプト間の差です。
00:00:02 ~> sleep 5 ## here I typed really quickly
00:00:05 ~> sleep 3 ## here I took about 2 seconds to enter the command
00:00:10 ~> sleep 30 ## more slow typing
00:01:35 ~>
@Cyrusの削除された回答に基づいて、追加の変数で環境を混乱させないバージョンを次に示します。
PROMPT_COMMAND='
_prompt(){
PROMPT_COMMAND="${PROMPT_COMMAND%-*}-$SECONDS))\""
printf -v PS1 "\[\e[0;32m\]%02d:%02d:%02d \W>\[\e[1;37m\] " \
"$(($1/3600))" "$((($1%3600)/60))" "$(($1%60))"
}; _prompt "$((SECONDS'"-$SECONDS))\""
bashバージョン4.2(echo $BASH_VERSION
)以降date
では、新しいprintfフォーマット文字列を使用した外部呼び出しを回避できます。$(date +%s)
ピースをと交換し$(printf '%(%s)T' -1)
ます。バージョン4.3以降では、-1
パラメーターを省略して、「引数なしはすぐに」という動作に依存することができます。
$SECONDS
と、シェルが起動してからの時間を追跡しなくなります
$SECONDS
、すべてのプロンプトに対して対話型シェルを再定義すると、予期しない動作が発生する可能性が高いと思います。ランタイムの評価に関連する何らかの理由でそれを使用する可能性がある他のシェル関数は、正しく動作しません。
PS1[3]=$SECONDS
PS1='${PS1[!(PS1[1]=!1&(PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600))
]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]/60%60), ${PS1[3]})):${PS1[1
]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]%60), ${PS1[3]})):${PS1[1
]#${PS1[3]%%*??}0}$((PS1[3]=(SECONDS), ${PS1[3]})):'$PS1
これは、計算によってフォーマットを処理します。そのため、数回展開されますが、サブシェルやパイプは実行されません。
単に$PS1
配列として扱い、より高いインデックスを使用して、プロンプト間で必要なすべての状態を格納/計算します。他のシェルの状態は影響を受けません。
00:00:46:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:00:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:43:[mikeserv@desktop tmp]$ sleep 10
00:00:33:[mikeserv@desktop tmp]$ sleep 10
00:00:15:[mikeserv@desktop tmp]$
00:00:15:[mikeserv@desktop tmp]$
00:00:02:[mikeserv@desktop tmp]$
00:02:27:[mikeserv@desktop tmp]$
多分少し分解できます...
まず、現在の値を保存します$SECONDS
。
PS1[3]=$SECONDS
次に、同時に自己参照$PS1[0]
し$PS1[1-3]
ながら常に正しい値を設定する方法で自己再帰的であることを定義します。この部分を取得するには、シェル数学式が評価される順序を考慮する必要があります。最も重要なことは、shell-mathは常にshell-mathの最後の業務です。何よりもまず、シェルは値を展開します。このようにして、を使用して割り当てた後、数式でシェル変数の古い値を参照できます$
。
最初に簡単な例を示します。
x=10; echo "$(((x+=5)+$x+x))" "$x"
40 15
シェルは、最初にドル記号参照が使用されている$x
場所の値を代入することによってそのステートメントを評価します。$
したがって、式は次のようになります。
(x+=5)+10+x
...その後、シェルはの値に5を加算し、$x
その後、式全体をに展開しますがx+10+x
、実際に割り当てられた値のみを参照変数に保持します。したがって、数式の拡張値は40ですが、最終的な値$x
は15です。
これは$PS1
、配列インデックスで利用される数学の拡張/評価のレベルがさらにあることを除いて、主に方程式が機能する方法です。
PS1='${PS1[!(PS1[1]=!1&(...))]#...}...'
なぜ私PS1[1]=!1
がそこで使用することを選んだのか本当にわかりません-それはおそらくばかげた美学だったと思います-しかし、これ$PS1[1]
はパラメータ置換のためにそれを拡張している間0を割り当てます。0とそれ以外のビット単位のANDの値は常に0になりますが&&
、左端のプライマリが0の場合はブール値のように短絡しないため、括弧付きの式は毎回評価されます。もちろん、その最初の省略記号はの初期値$PS1[2,3]
が設定される場所であるため、これは重要です。
とにかく、$PS1[1]
プロンプト描画の間に改ざんされたとしても、ここでは0になることが保証されています。括弧内に...
PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600
... $PS1[2]
の違いに割り当てられている$PS1[3]
とする$SECONDS
と、$PS1[3]
その値の商を割り当てられ、3600のすべての値は、ここで初期化されます。など:
${PS1[1]#${PS1[3]%%*??}0}
... $PS1[3]
内部に2桁以上ある場合、内部展開はnull $PS1[1]
です。0であることがわかっている$PS1[3]
ので、何も代入されない場合は置き換えられ、それ$PS1[1]
以外の場合もその値に展開されます。このようにして、$PS1[3]
割り当ての反復ごとに1桁の値だけが先行ゼロを展開し、$PS1[3]
それ自体が直後に60を法として展開され、同時に時間、分、秒ごとに次の連続的に小さい値が同時に割り当てられます。
プロンプトが次に表示されたときにもう一度比較できるように$PS1[3]
、現在の値で上書きされる最後の反復まですすぎ、繰り返します。$SECONDS
$SECONDS
これまでに見つけた最良の解決策はこれです:https : //github.com/jichu4n/bash-command-timer
これ[ 1s011 | May 25 15:33:44 BST ]
は、実行されたコマンドの後に右側に経過時間を表示するので、PS1が煩雑になることはありません。
文字列と時刻の形式全体を構成できます。色や精度も設定可能です。ミニマリストにとっては少々多いかもしれませんが、それはかなりクールです。