1つの端末を終了するときに他の端末のbash履歴を更新する


14

ここで求められているように私は、この質問が曖昧にされていません知って更新し続ける(と重複こちら)。

私が達成しようとしていることは少し異なります。入力するたびlsにプロンプトをファイルに書き換えるという考えが好きではありません(history -a; history -c; history -r)。

終了時にファイルを更新したいと思います。それは簡単です(実際にはデフォルトです)が、書き換える代わりに追加する必要があります:

shopt -s histappend

ここで、端末が閉じられたときに、更新を認識できるように、開いたままになっている他のすべてのものを作成したいと思います。

入力$PS1するたびにチェックすることなくこれを行うことを好みcommandます。何らかの信号をキャプチャする方が良いと思います。どうしますか?不可能な場合は、おそらく簡単cronjobですか?

このパズルをどのように解決できますか?


1
zshはこれをすぐに実行できることに注意してください(履歴共有を微調整するための多くのオプションがあります)。
ジル 'SO-悪であるのをやめる'

ありがとう@Gilles; おかしい、何年もLinuxを使っていて、私は何も試していないbash。たぶん、楽しみのために、何か新しいものをチェックする時です。
ベコ博士

回答:


14

創造的で関係のある信号ですか?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の内部イベントのいずれかに信号ハンドラー設定します。このEXITイベントは、シェルの制御された終了です。一方、USR1SIGUSR1、意味のないシグナルです。

シェルが終了するたびに、次のことを行います。

  • すべての履歴を明示的にファイルに追加します。
  • SIGUSR1ハンドラーを無効にして、このシェルがシグナルを無視するようにします。
  • bash同じユーザーから実行中のすべてのプロセスにシグナルを送信します。

ときにSIGUSR1到着し、我々 :

  • 履歴ファイルからシェルのメモリ内履歴リストにすべての新しいエントリをロードします。

あなたがヒットするまでためバッシュハンドル信号道、あなたが実際に新しい履歴データを取得することはありませんEnter次回、これは任意のより良いその前面に置くよりも行いませんので、history -nPROMPT_COMMAND。ただし、何も起きていない場合は常にファイルの読み取りを保存し、シェルが終了するまで書き込みは一切行われません。


ただし、まだいくつかの問題があります。1つ目は、デフォルトの応答SIGUSR1はシェルを終了することです。他のbashプロセス(たとえば、シェルスクリプトの実行)は強制終了されます。.bashrc非対話型シェルによってロードされません。代わりに、という名前のファイルBASH_ENVがロードされます。環境内の変数をグローバルに設定して、ファイルを指すようにできます。

trap '' USR1

その中の信号を無視します(問題を解決します)。

最後に、これはあなたが要求したことを行いますが、あなたが得る順序は少し珍しいでしょう。特に、個別にロードされて保存されると、履歴のビットが異なる順序で繰り返されます。それはあなたが求めているものに本質的に内在していますが、上向き矢印の歴史はこの時点ではあまり有用ではないことに注意してください。ただし、履歴の置換などは共有され、適切に機能します。


.bashrcファイル内でタイムスタンプを有効にし、cronジョブのようなものが定期的に来てファイルを定期的にSIGUSR1並べ替え、あなたのスニペットを送信し、時系列の上矢印履歴を取り戻すことができるかどうか疑問に思いますか?
forquare

それはきちんとしたソリューションですが、事実のために他のプロセスはUSR1で終了します。この動作はUSR2でも発生しますか?
ベコ博士

驚いたので、2番目のコメントを追加します。プロセスがTERMをUSR1と関連付けるのはなぜですか?USR1はユーザーだけが使用するものではありませんか?これは何linux bugですか?? 他のプロセスがUSR1をキャッチしているのはなぜですか?(ここで説明するつもりはないことを知っていますが、正しい場所でこれを明らかにするかもしれません)
ベコ博士

ほとんどすべての信号のデフォルトの動作は終了することです。POSIXで指定されています。バグではありません。ただし、Bashを使用すると、すべてのプロセスでシグナルが無視されるように指定できます。そのため、この目的には適しています。
マイケルホーマー

@MichaelHomerに感謝します。この仕様書BASH_ENVは、この回答に記載されているようにあなたが意図したものですか?それとも、この悪を止めるより標準的な方法を知っていますか?
ベコ博士
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.