すべてのコマンドに対してエイリアスを強制的に「追加」します。

すべてのコマンドに対してエイリアスを強制的に「追加」します。

より良い表現方法がないので、すべてのコマンドにタイミングエイリアスを強制的に追加できますかbash

たとえば、特定のユーザーがいてコマンドが実行されるたびに、常にdatebefore と after または で実行されますtime

可能ですか?可能であればどのように達成できますか?

答え1

コマンドラインの起動時とプロンプトが表示されたときに記録できます。 Bashはすでに履歴内の各コマンドラインの開始日を追跡しており、次のプロンプトが表示されるタイミングを確認できます。

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

これは2番目の解決策と壁時計時間のみを提供します。より良い解像度が必要な場合は、ナノ秒形式をサポートdateする外部コマンド%Nとコマンドを実行する前に、呼び出されるトラップを使用してDEBUG時間を測定する必要があります。date

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo "Wall clock time: $(date +"%s.%N - $date_before" | bc)"
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_wall_clock_time

トラップを使用しても、DEBUG各コマンドのプロセッサ時間を自動的に表示したり、プロンプトよりも識別する方法はないと思います。


別のシェルを使用する場合は、zshで各コマンドの時間レポートを取得する方法は次のとおりです(他の操作では機能しません)。

REPORTTIME=0

この値は任意の整数値に設定できREPORTTIME、プロセッサ時間をこの秒以上使用する命令のみがタイミング情報を表示します。

Zshは、変数が呼び出されるcshからこの機能を継承しますtime

答え2

ここで選択できるオプションは、シェルによって異なります。対話型シェルコマンドの前に実行されるzsh便利なフック機能があります。preexec()この名前で関数を作成すると、いくつかのことができます。precmd()次のヒントが描画される前に実行され、次のヒントの後に実行される関数を呼び出して後続のアクションを実行することもできます。あなたのコマンドが完了しました。

この関数ペアを作成すると、プロンプトでコマンドを実行する前後に必要なコマンドを実行できます。これを使用して、シェル使用量を記録し、ロックを作成し、環境をテストしたり、例のようにコマンドの実行に費やされた時間またはリソースを計算したりできます。

この例では、コマンドを実行する前に基準タイムスタンプを生成し、コマンドを実行するのにかかる時間を計算し、プロンプトの前に出力またはpreexec()記録しますprecmd()。例:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

メモ:この特定の例には、より単純な組み込み関数があります。 ZSHでランタイムレポートを開くだけで、これは自動的に行われます。

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

より実用的な実装では、preexec()これを使用してシェルが内部的に実行されていることを確認しtmuxscreenその場合は現在実行中のコマンドアップストリームに関する情報をタブ名に表示するように送信します。

残念ながら、この小さなメカニズムはbashには存在しません。これは男のものですコピーしてみてください。また見てくださいザイルズの答えこのような素晴らしい小さなハッキングのために。

答え3

最も簡単な方法は、おそらくそれを設定することですPROMPT_COMMAND。よりバッシュ変数:

PROMPT_COMMAND設定すると、この値は
各デフォルトプロンプト()が印刷される$PS1前に実行されるコマンドとして解釈されます。

たとえば、既存のプロンプトコマンドを上書きしたくない場合は、次のようにします。

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"

答え4

〜のようにwjandreaが指摘しました。ザイルズの答え動作しません。

  • 部分的には、美容上の理由でwjandreaがこの問題を解決しました。
  • その理由の1つは、DEBUGトラップコマンドがPROMPT_COMMANDコマンドの直前に実行されるため、実行時を測定したいユーザー入力コマンドの開始時間が失われるためです。

幸いなことに、DEBUGトラップコマンドはいつこのようなことが起こるのかがわかります そして予防することができます。したがって、Gillesの回答に基づいて(DNA断片と結合)ここに私の答えと非常に似ています。)、私達は構成できます

call_date_before_command () {
  if [ "$BASH_COMMAND" != "print_wall_clock_time" ]
  then
        command_flag=1
        date_before=$(date +%s.%N)
  fi
}
print_wall_clock_time () {
  if [ "$command_flag" ]
  then
        echo "Wall clock time: $(date +"%s.%N - $date_before" | bc)"
  fi
  command_flag=
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_wall_clock_time

実行前にwhereが呼び出された場合はcall_date_before_command何も実行せず、ユーザーが実際にコマンドを実行したときにのみ情報を報告します(Enterキーを押すのではありません)。print_wall_clock_timeprint_wall_clock_time

誤って両方のいずれかをインタラクティブにオーバーライドする可能性を減らすためにcall_date_before_command、、およびの名前を変更できます。command_flagprint_wall_clock_timeTwas_brillig_and_the_slithy_tovesDid_gyre_and_gimble_in_the_wabeAll_mimsy_were_the_borogoves

関連情報