bash_historyが常に同じように見え、非ログインシェルを使用して更新されないのはなぜですか?

bash_historyが常に同じように見え、非ログインシェルを使用して更新されないのはなぜですか?

過去数日間、システムをシャットダウンし(Debianテスト)、bashセッションを開始し、上矢印キーを押すたびに最初に使用したときに履歴キャッシュをクリアするコマンドが表示されることを確認しました。history -c。どうやってこれが起こるのかわかりませんが、履歴を消去して上向き矢印を押しても大丈夫です。ただし、他のシェルを起動すると機能しません(再起動またはシャットダウンするたびに、またはログに記録するときは少なくなります)。から)。

すべての方法(手動削除も含む)を試したので、.bash_historyアイデアはありません。

$ echo $SHELL
/bin/bash
$ /bin/bash --version
GNU bash, version 4.2.45(1)-release (i486-pc-linux-gnu)
$ echo $HISTFILE
/home/braiam/.bash_history

質問に追加する情報を見つけるときls -l .bash_history(愚かなように見えないように)走って、次の質問を見つけました。

$ ls -l .bash_history 
-r--------. 1 braiam braiam 59372 Jul 26 20:18 .bash_history

しかし、ランニングはchmod +w .bash_history一日を救うことができませんでした。今どうしてこんなことがあったのか気になりますね…

ファイルを削除した後.bash_history、今のところ記録はありません。手がかりを見つけるために.bashrcをチェックしました。

cat .bashrc | grep -i hist
# don't put duplicate lines or lines starting with space in the history.
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

ログインしていない(GNOME端末)シェルでAshの回答に従って、次の操作を行います。

braiam@bt:~$ echo abacaba; echo $$
abacaba
15372
braiam@bt:~$ 

次に、別の非ログインシェルを起動します。

braiam@bt:~$ strace -o e -s 256 -p 15372
Process 15372 attached - interrupt to quit

最初のシェルに戻り、次のように入力しますhistory -a

braiam@bt:~$ echo abacaba; echo $$
abacaba
15372
braiam@bt:~$ history -a
braiam@bt:~$ 

straceを持つシェルには何もありません。

braiam@bt:~$ strace -oe -s 256 -p 15372
プロセス 15372 添付 - 割り込み終了

私はここで希望をほとんどあきらめることができなかったので、straceのマニュアルを調べることにし、-o結果をファイルにダンプすることを知って、cat e次のように返しました。

cat e
read(0, "\33", 1)                       = 1
read(0, "[", 1)                         = 1
read(0, "A", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "history -w", 10)              = 10
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "\33", 1)                       = 1
read(0, "[", 1)                         = 1
read(0, "A", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "\10a", 2)                     = 2
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "\r", 1)                        = 1
write(2, "\n", 1)                       = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGALRM, {0x80a1080, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_IGN, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGWINCH, {0x80a09e0, [], 0}, {0x80e9550, [], SA_RESTART}, 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80a0e30, [], 0}, 8) = 0
time(NULL)                              = 1378047084
stat64("/home/braiam/.bash_history", {st_mode=S_IFREG|0600, st_size=44, ...}) = 0
open("/home/braiam/.bash_history", O_WRONLY|O_APPEND|O_LARGEFILE) = 3
write(3, "history -w\nhistory -a\n", 22) = 22
close(3)                                = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80a0e30, [], 0}, 8) = 0
time(NULL)                              = 1378047084
rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [], 8) = 0
ioctl(255, TIOCSPGRP, [15372])          = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGINT, {0x80a0e30, [], 0}, {0x80a0e30, [], 0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
ioctl(0, TIOCGWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(0, TIOCSWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT QUIT ALRM TERM TSTP TTIN TTOU], [], 8) = 0
rt_sigaction(SIGINT, {0x80e9d00, [], 0}, {0x80a0e30, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGALRM, {0x80e9d00, [], 0}, {0x80a1080, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 0}, 8) = 0
rt_sigaction(SIGTSTP, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTSTP, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {0x80e9d00, [], 0}, {SIG_IGN, [], 0}, 8) = 0
rt_sigaction(SIGTTIN, {SIG_IGN, [], 0}, {0x80e9d00, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGWINCH, {0x80e9550, [], SA_RESTART}, {0x80a09e0, [], 0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "\33]0;braiam@bt: ~\7\33[01;31mbraiam@bt\33[00m:\33[01;34m~\33[00m$ ", 56) = 56
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0,  <unfinished ...>

したがって、この声明によると、何の問題もありません。次に、何の喜びもなく別の非ログインシェルを開きます。履歴が読み込まれませんでした。 Aは、cat .bash_historyファイルが実際には埋められているが、ログインではないシェルではそれを許可しないことを示します。

今両方試してみました。strace -o /tmp/e -s 512 bash ここ(文字数制限に比べて長すぎます)strace -o /tmp/e -s 512 gnome-terminal ここ(どちらもpastebin.comからのものです。申し訳ありません。)ここ元の設定を使用してください(.bash_historyに対する-w権限を除く)。

次に、Ctrl + Alt + F1でログインしようとしてログインし、上矢印を押して指を横切るとうまくいきました!しかし、これはまだ疑問です。非ログインシェルが履歴をロードしないのはなぜですか?

答え1

試してみましたhistory -c && history -wか?

history -c書き込み関数キャッシュをクリアし、history -w.bash_history(なし)の書き込み関数キャッシュにコマンドを書き込みます。

もう1つのオプションは、bashの履歴を消去して次に/dev/null > ~/.bash_history接続することです。~/.bash_history/dev/nullln -sf /dev/null ~/.bash_history

現在のシェルセッションを保存したくない場合は、コマンドを実行してhistory -r履歴キャッシュを初期状態(セッション開始前)にリセットする必要があります。その後、ログアウトすると、履歴キャッシュのコマンド(シェルセッションを開始する前と同じ)が記録されます。.bash_history

答え2

これが発生する可能性がある理由の1つは、シェルが正常にシャットダウンされていないか、シェルが実行中に更新を探しているためです。

このシナリオをテストするには、実行中のシェルなどでいくつかのhistory -a固有のコマンドを実行してから、新しいシェルを起動してみてください。echo abacaba新しいシェルが最初のシェルから更新を受け取ると、履歴ファイルの書き込みと読み取りが正しく機能します。でもそれでなければ何か問題があるので、私がstrace直接診断してみましょう。

また、確認する必要があるのは、HOME変数が変更されておらず、passwdユーザーファイルに設定されているのと同じパスに設定されていることです。

straceを使用した診断

  • 殻の中で、echo abacaba; echo $$
  • 他のシェルからstrace -o e -s 256 -p $PID= 最初のシェル$PID$$出力
  • 最初の殻ではhistory -a
  • straceを停止し、どのように進行しているかを確認してくださいhistory -a。 open() および write() 呼び出しが必要です。

非対話型シェル

奇妙なことに、非対話型シェルはシェル履歴を取得できませんが、これはさまざまな理由で説明される可能性があります。より多くの診断が役に立ちます。

非インタラクティブシェルの開始を修正してstraceを挿入できる場合は、Straceを使用して支援を受けることができます。たとえば、次は、straceを使用するように変更されたシェル起動コマンドを示しています。

bash /home/jack/bin/jacks_script
strace -f -o /tmp/e -s 512 bash /home/jack/bin/jacks_script

もちろん、一度に複数を実行すると上書きさ/tmp/eれます。

を使用してくださいgrep open /tmp/e。シェルがbash_historyファイルをロードした場合は、ファイルのフルパスを表示する必要があります。したがって、このコマンドを使用すると、(1)履歴ファイルが開かれているかどうか、および(2)履歴ファイルへのパスが期待されているような2つのチェックが可能になります。

痕跡がない

シェルにhistoryオプションセット(set -o historybash用)があることを確認してください。

不明なことの1つは、HISTFILEシェルがチェックするときです。たとえば、に設定すると、.bash_profileシェル履歴の読み取りに影響を与えるかどうかはわかりません。これはシェルが起動した後ですが、ユーザーに最初のコマンドプロンプトが表示される前です。

答え3

単に設定を解除すると$HISTFILE(記録ファイルへのパスを含む)、現在のセッションで履歴を使用する機能には影響しません。

unset HISTFILE

答え4

私がしたことは、次のようにHISTFILESIZEファイルで0に設定することでした。.bashrcデブスロンコメントで言いました。

[...]
HISTFILESIZE=0
[...]

関連情報