この質問は、ここで更新を続けて(そしてここで複製して)尋ねられるので、曖昧ではないことを私は知っています。
私が達成しようとしていることは少し異なります。 ls
ごとにファイルをすぐに書き換えるというアイデアは好きではありません。 (history -a; history -c; history -r
と入力します 。
終了時にファイルを更新したいのですが。これは簡単ですが(実際にはデフォルト)、書き直す代わりに追加する必要があります:
shopt -s histappend
さて、ターミナルが閉まっているときは、開いたままになっている他のすべての人にアップデートを知らせたいと思います。
$PS1
で確認せずにこれを行うことを好みます すべてのcommand
で 私がタイプすること。ある種の信号を捉えたほうがいいと思います。どのようにそれをしますか?不可能な場合は、単純な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
を無効にします ハンドラーを作成し、このシェルに信号を無視させます。 - 実行中のすべての
bash
にシグナルを送信します 同じユーザーからのプロセス。
SIGUSR1
の場合 到着しました:
- すべての新しいエントリを履歴ファイルからシェルのメモリ内履歴リストにロードします。
Bashが信号を処理する方法のため、 Enter を押すまで、実際には新しい履歴データを取得しません。 次回は、history -n
を配置するよりもこの面でうまくいくことはありません。 PROMPT_COMMAND
に 。ただし、何も起こらなかったときにファイルの読み取りを常に節約し、シェルが終了するまで書き込みはまったく行われません。
ただし、ここにはまだいくつかの問題があります。 1つ目は、SIGUSR1
に対するデフォルトの応答です。 シェルを終了することです。その他のbash
プロセス(たとえば、シェルスクリプトの実行)は強制終了されます。 .bashrc
非対話型シェルによってロードされません。代わりに、BASH_ENV
という名前のファイル ロードされます:環境内でその変数をグローバルに設定して、次のファイルを指すようにすることができます:
trap '' USR1
その中の信号を無視します(これで問題が解決します)。
関連:サーバーが仮想か物理かを確認するためのターミナルコマンド?最後に、これはあなたが要求したことを行いますが、あなたが得る順序は少し珍しいでしょう。特に、履歴の一部は個別に読み込まれて保存されるため、異なる順序で繰り返されます。これは基本的にあなたが求めているものに固有のものですが、この時点で上向きの矢印の履歴はあまり役に立たなくなることに注意してください。ただし、履歴の置換などは共有され、うまく機能します。