タイムスタンプが指定されたコマンド履歴を端末に継続的に出力する方法は?

タイムスタンプが指定されたコマンド履歴を端末に継続的に出力する方法は?

簡単なものを使うニックネーム1つ以上の端末ウィンドウで「trace」コマンドを有効にします。

alias trackmi='export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"'

それから私はちょうどtail -f私のものです。.bash_history即時のフィードバックを得るには、ワークスペースの他の端末にファイルを保存してください。起動したばかり無限の歴史 私の記録フォーマットを更新しました(export HISTTIMEFORMAT="[%F %T] ")。.bashrc。もちろん、このhistoryコマンドはタイムスタンプを表示します。しかし、滞在履歴ファイル自体は次のとおりです。

#1401234303
alias
#1401234486
cat ../.bashrc 

historyUnix時間を変換し、数値を含むコマンドと同様に、コマンド全体を1行に表示するにはどうすればよいですか?

578  [2014-05-27 19:45:03] alias
579  [2014-05-27 19:48:06] cat ../.bashrc 

...そしてそれに従ってください。または、historyコマンドの出力を端末に継続的に出力する方法をお探しですか?

答え1

GNUの使用awk:

tail -fn+1 ~/.bash_history | awk '
  /^#/{printf "%-4d [%s] ", ++n, strftime("%F %T", substr($0, 2)); next}; 1'

答え2

デフォルトでは、シェルのデフォルトでいくつかのコマンドのみを使用する分割画面xtermで実行される最終製品は次のとおりです。

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

スクリーンショットに示されているよりも粗雑なアプローチは次のとおりです。

PS1='$( { date ; fc -l -0 ; } >${TGT_PTY} )'$PS1

出力したい画面で実際にインタラクティブシェルを実行したときに${TGT_PTY}コマンドから得られた内容はどこにありますか?ttyあるいは、本質的にファイルリダイレクトのターゲットであるため、書き込み可能なすべてのファイルを使用できます。

私は使うフーティ構文は次のとおりです。擬似端末私はそれがxtermの一種であると仮定しているので、簡単にVTを専用にすることができ、ストリーミング履歴には常に単一のキーの組み合わせCTRL-ALT-Fnしか必要ありません。私はおそらく両方の概念を組み合わせて専用のvtscreenセッションにしますがtmux

新しく起動したシステムには、/bin/login一般的なLinuxコンソールgettyにある一般的なプロンプトが表示されます。CTRL-ALT-F2あまり一般的でないコンソールにアクセスするためにボタンを押すと、コンソールではなく1つのkmsconように動作します。コマンドを入力して応答を受け取ります。xtermttytty/dev/pts/0

通常、xterms は複数の目的で単一の端末デバイスを再利用します。擬似端末- したがって、ターミナルタブまたはウィンドウを切り替えてX11で同様の操作を実行すると、おそらく同様の出力が得られます/dev/pts/[0-9]*。ただし、キーの組み合わせを介してアクセスされる仮想端末コンソールはCTRL-ALT-Fn実際の端末装置であるため、一意の/dev/tty[0-9]*名前を持ちます。

そのため、コンソール2にログインしてttyプロンプトに入力すると応答が発生しますが、/dev/pts/0コンソール1で同じ操作を実行すると出力はです/dev/tty1。とにかくコンソール2に戻り、次の操作を行います。

bash
PS1='$( { date ; fc -l -0 ; } >/dev/tty1 )'$PS1

明確な効果はありません。引き続きさらにコマンドを入力し、CTRL-ALT-F1もう一度押してコンソール1に切り替えました。そこで、<date_time>\n<hist#>\t<hist_cmd_string>コンソール2に入力したすべてのコマンドに対して同様の重複エントリが見つかりました。

ただし、端末デバイスに直接書き込まない限り、他のオプションは次のようになります。

TGT_PTY=
mkfifo ${TGT_PTY:=/tmp/shell.history.pipe}
{   echo 'OPENED ON:'
    date
} >${TGT_PTY}

だからおそらく...

less +F ${TGT_PTY}

おおよそのプロンプトコマンドは仕様を満たしていません。フォーマット文字列もなく、dateフォーマットオプションもありませんfc。しかし、メカニズムには多くは必要ありません。プロンプトが最後の履歴コマンドをレンダリングするたびに、現在の日時が指定したとおりに${TGT_PTY}記録されます。文書。とても簡単です。

シェル履歴の表示と印刷がfc主な目的です。そうでなくても組み込みシェルですdate。 Inはzsh fcあらゆる種類の素晴らしい書式設定オプションを提供し、そのいくつかはタイムスタンプに適しています。もちろん、上記のようにbash's'もhistory同じことができます。

よりきれいな出力のために、よりよく説明された技術を使用することができます。ここプロンプトシーケンス内のサブシェルで追跡および処理する必要がありますが、現在のシェルで永続的なトレース変数を設定します。

仕様に合わせてフォーマットする移植可能な方法は次のとおりです。

_HIST() { [ -z ${_LH#$1} ] ||
    { date "+${1}%t[%F %T]"
      fc -nl -0 
    } >${TGT_PTY}
    printf "(_LH=$1)-$1"
}

: "${_LH=0}"
PS1='${_LH##*[$(($(_HIST \!)))-9]}'$PS1

私は実装しました最後の歴史カウンタは$_LH最新の更新のみを追跡するため、同じ履歴コマンドを2回作成しません。たとえば、Enter キーを押す場合にのみ使用できます。関数がサブシェルから呼び出されても、値を保持するために現在のシェルで変数を増やすために必要ないくつかの議論があります。これは以下で行われる。協会

出力は次のとおりです。<hist#>\t[%F %T]\t<hist_cmd>\n

しかし、これは完全に移植可能なバージョンにすぎません。これにより、bash少ないリソースを使用し、シェル組み込み機能のみを実装できます。これは、押すたびに実行されるコマンドであると考えると理想的です[ENTER]。これには2つの方法があります。

_HIST() { [ -z ${_LH#$1} ] || {
        printf "${1}\t[%(%F %T)T]"
        fc -nl -0
    } >${TGT_PTY}
    printf "(_LH=$1)-$1"
}
PROMPT_COMMAND=': ${_LH=0};'$PROMPT_COMMAND
PS1='${_LH##*[$(($(_HIST \!)))-9]}'$PS1

または、コマンドを使用してbash次のようにhistory関数を定義できます。_HIST

_HIST() { [ -z ${_LH#$1} ] || 
        HISTTIMEFORMAT="[%F %T]<tab>" \
        history 1 >${TGT_PTY}
    printf "(_LH=$1)-$1"
}

両方の方法の出力は次のとおりです。<hist#>\t[%F %T]\t<hist_cmd>\nこのhistory方法には先行スペースが含まれます。しかし、history私はタイムスタンプを取得するために参照されたコマンドが完了するのを待つ必要がないため、この方法を使用するとタイムスタンプがより正確になると思います。

前述uniqのように、いずれかの方法でストリームをフィルタリングする限り、どちらの場合もステータス追跡を回避できます。mkfifo

ただし、プロンプトでこれを行うと、プロンプトの更新操作によって必要なときにのみ常に更新されることを意味します。これはとても簡単です。

tail現在やっているのと同じようなことをすることもできますが、

HISTFILE=${TGT_PTY}

答え3

形式を自由に試してみてください。しかし、これは(私の考えでは)好きなように動作します...パスのどこかに保存して実行可能にして楽しんでください。

#!/bin/bash
count=$(  echo "scale=0 ; $(cat ~/.bash_history | wc -l ) / 2" | bc -l )
tail -f ~/.bash_history | awk -v c=$count '{if($1 ~/^#/){gsub(/#/, "", $1);printf "%s\t", c; "date \"+%F %T\" --date @" $1 | getline stamp; printf "[%s]\t",stamp;c++}else{print $0}}'

私はそれが最適化できると確信していますが、あなたはアイデアを得ます。

クイックノート:〜/ .bash_historyはカウントを追跡しないため、最初にエントリ数を決定します。次に、awkマジックを使用してフォーマットを正しく指定し、アイテム数を追跡します。

関連情報