コマンド履歴は終了時にのみ保存されるのはなぜですか

コマンド履歴は終了時にのみ保存されるのはなぜですか

タブ/ターミナルごとに異なる履歴ファイルを保存しようとしていますが、コマンドの実行直後に保存することができません。履歴は「exit」を実行したときにのみ保存されます。

これは問題です。私が実現したいのは、端末またはコンピュータがクラッシュした場合に備えて履歴のコピーを保持することです。

インターネットで調べたところ、私の .bashrc ファイルには次の内容が記載されていました。

export HISTFILE="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')"
export HISTCONTROL=ignoreboth
export HISTFILESIZE=10000
export HISTSIZE=10000
shopt -s histappend
PROMPT_COMMAND=$(history -a; $PROMPT_COMMAND)

何が間違っているのか分かりますか?

ありがとう。

答え1

PROMPT_COMMANDの割り当てが間違っています。

PROMPT_COMMAND=$(history -a; $PROMPT_COMMAND)

'history -a' (出力は生成されません) を実行し、次に $PROMPT_COMMAND (起動スクリプトでは空になる場合があります) を実行し、これら 2 つのコマンドの出力 (空の文字列) を PROMPT_COMMAND に割り当てます。必要なのは次のようになります。

PROMPT_COMMAND='history -a'

既存のコマンドに追加したい場合は、

PROMPT_COMMAND+="history -a${PROMPT_COMMAND+=; }$PROMPT_COMMAND"

答え2

理解できない理由で、これは機能します:

export HISTFILE_NEW="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')"
export HISTCONTROL=ignoreboth
export HISTFILESIZE=10000
export HISTSIZE=10000
shopt -s histappend
PROMPT_COMMAND="history -w $HISTFILE_NEW; $PROMPT_COMMAND"

これは、

export HISTFILE="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')"
export HISTCONTROL=ignoreboth
export HISTFILESIZE=10000
export HISTSIZE=10000
shopt -s histappend
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

もちろん、最初の解決策は、新しいコマンドが書き込まれるたびに履歴全体が保存されるため、理論的に優れた解決策 (2 番目) よりも遅くなります。

したがって、なぜこのようなことが起こるのか、また、これをどのように解決できるのかをご存知の方がいらっしゃいましたら、大変ありがたく思います。

答え3

文字通りの質問ではなく、意図に答えます。

スクリプトの使用を参照してください。これにより、コマンドとその出力が提供されます。カーソル位置を使用するコマンドは後で解読するのが難しいため、これは万能薬ではないことに注意してください。

名前スクリプト - ターミナルセッションのTypescriptを作成する

概要 スクリプト [-a] [-c コマンド] [-f] [-q] [-t] [ファイル]

説明 スクリプトは、端末に印刷されるすべてのものをタイプ スクリプトにします。タイプ スクリプト ファイルは後で lpr(1) を使用して印刷できるため、課題の証明として対話型セッションのハード コピー記録が必要な学生にとって便利です。

引数ファイルが指定されている場合、スクリプトはすべてのダイアログをファイルに保存します。ファイル名が指定されていない場合、タイプスクリプトはファイル typescript に保存されます。

オプション:

  -a'        Append the output to file or typescript, retaining the priorcontents.

-c COMMAND 対話型シェルではなく COMMAND を実行します。これにより、stdout が tty でない場合に異なる動作をするプログラムの出力をスクリプトで簡単にキャプチャできます。 -f' 各書き込み後に出力をフラッシュします。これは遠隔協力に適しています。1 人が 'mkfifo foo; script -f foo' を実行し、もう 1 人が 'cat foo' を使用して実行されている内容をリアルタイムで監視できます。

-q' 静かにしなさい。

-t' タイミング データを標準エラーに出力します。このデータには、スペースで区切られた 2 つのフィールドが含まれます。最初のフィールドは、前回の出力から経過した時間を示します。2 番目のフィールドは、今回出力された文字数を示します。この情報を使用して、現実的な入力および出力の遅延でタイプ スクリプトを再生できます。

スクリプトは、フォークされたシェルが終了すると終了します (Bourne シェル (sh(1)) を終了するには control-D、C シェル (csh(1)) の場合は exit、logout、または control-d (ignoreeof が設定されていない場合) です)。

vi(1) などの特定の対話型コマンドは、Typescript ファイルにゴミを作成します。スクリプトは、画面を操作しないコマンドで最も効果的に機能し、その結果はハードコピー端末をエミュレートすることを目的としています。...

Google で「man script」を検索してください。特定の OS がある場合は、それを含めてください。これは Linux バージョンですが、*BSD、Mac 用のほぼ同一のバージョンが存在します。おそらく Windows ポートもあるでしょう。

関連情報