ここで尋ねられるので、私はこの質問が曖昧ではないことを知っています 更新を続けます (そして 重複 ここで)。
私が達成しようとしていることは少し異なります。 ls
(history -a; history -c; history -r
)と入力するたびにプロンプトがファイルを書き換えるというアイデアは好きではありません。
終了時にファイルを更新したいのですが。これは簡単です(実際にはデフォルトです)が、書き直す代わりに追加する必要があります。
shopt -s histappend
さて、端末が閉じているときは、開いたままになっている他のすべての端末に更新を認識させたいと思います。
入力するすべてのcommand
で$PS1
を介してチェックせずにこれを行うことを好みます。ある種の信号をキャプチャしたほうがいいと思います。どうしますか?不可能な場合は、単純なcronjob
?
どうすればこのパズルを解くことができますか?
創造的で関与するシグナル、あなたは言いますか? OK:
trap on_exit EXIT
trap on_usr1 USR1
on_exit() {
history -a
trap '' USR1
killall -u "$USER" -USR1 bash
}
on_usr1() {
history -n
}
.bashrc
でそれをチャックして行きます。これはシグナルを使用して、すべてのbash
プロセスに、別のプロセスが終了したときに新しい履歴エントリをチェックするように指示します。これはかなりひどいですが、実際に機能します。
どのように機能しますか?
trap
はシグナルハンドラーを設定します システムシグナルまたはBashの内部イベントの1つに対して。 EXIT
イベントはシェルの制御された終了であり、USR1
はSIGUSR1
であり、私たちが流用している意味のないシグナルです。
シェルが終了するたびに、次のことを行います。
SIGUSR1
ハンドラーを無効にして、このシェルを ignore シグナルにします。bash
プロセスにシグナルを送信します。SIGUSR1
が到着すると、次のようになります。
Bashがシグナルを処理する方法のため、ヒットするまで実際には新しい履歴データを取得しません Enter 次回は、 history -n
をPrompt_COMMAND
に入れるよりも、この面でうまくいくことはありません。ただし、何も起こらなかったときにファイルの読み取りを常に節約し、シェルが終了するまで書き込みはまったく行われません。
ただし、ここにはまだいくつかの問題があります。 1つ目は、 SIGUSR1
へのデフォルトの応答は終了することです シェルです。その他のbash
プロセス(シェルスクリプトの実行など)はすべて強制終了されます。 .bashrc
は、非対話型シェルによってロードされません。代わりに、 BASH_ENV
という名前のファイルがロードされます :環境内のその変数をグローバルに設定して、次のファイルを指すようにすることができます。
trap '' USR1
それらの中の信号を無視するためにその中に(問題を解決します)。
最後に、これはあなたが要求したことを行いますが、あなたが得る順序は少し変わっています。特に、履歴のビットは、別々にロードおよび保存されるため、異なる順序で繰り返されます。これは本質的にあなたが求めているものに固有のものですが、上向きの履歴はこの時点ではるかに役に立たなくなることに注意してください。 履歴置換 などは共有され、うまく機能します。