不要将当前 bash 会话保存到历史记录中

我注意到,当打开 .bash_history时,它只包含来自我上一个会话的条目,似乎当前会话只在退出时附加。有什么方法可以防止当前会话保存?如果你知道如何做到这一点,甚至崩溃 bash也是一种选择。我发现我可以 kill -9的过程,但如果有一个更好的方式我想知道。

66409 次浏览

Unset the $HISTFILE variable

$ unset HISTFILE

If HISTFILE is unset, or if the history file is unwritable, the history is not saved.
http://www.faqs.org/docs/bashman/bashref_106.html

Perhaps more elegant than crashing bash would be to use the history -c command to clear the history of the current session. Then, there's nothing to save (it even wipes itself from the history).

That should do:

HISTFILE=

unset the HISTFILE.

There's another option, similar to history -c, but that does not wipe anything previous to the current session.

It is history -r, which reloads the history from the HISTFILE, like if you just logged in.

I don't know if this works or is available in any bash version previous to 4.3.11, but I though it would be useful to include it to the list.

Here's an example showing the difference between this command and the -c one:

user@host:~$ # I Just logged in
user@host:~$ history | tail -n6 # this shows commands from the previous session, which ends at item 4682 as well as from the current one
4679  2014-08-23 17:15:29 # Previous session
4680  2014-08-23 17:15:33 # Still the previous session
4681  2014-08-23 17:15:37 # note the datetime
4682  2014-08-23 17:15:44 exit
4683  2014-08-23 17:17:25 # I Just logged in
4684  2014-08-23 17:19:54 history | tail -n6 # this shows the last command, and the ones from the previous session
user@host:~$ # This is a secret command, so I need to remove the traces of this session
user@host:~$ history -r
user@host:~$ history | tail -n5 # Note that I went back to item 4682, and there are no traces of history -r command
6242  2014-08-23 17:15:29 # Previous session
6243  2014-08-23 17:15:33 # Still the previous session
6244  2014-08-23 17:15:37 # note the datetime
6245  2014-08-23 17:15:44 exit
6246  2014-08-23 17:22:26 history | tail -n5 # Note that I went back to item 4682, and there are no traces of history -r command
user@host:~$ history -c # instead if I issue history -c
user@host:~$ history # everything disappears
5248  2014-08-23 17:23:13 history # everything disappears
user@host:~$

The following works for me.

 export HISTFILE=/dev/null

Note that it has a space in front of it. Most modern distros would not add commands that are entered after a space to bash history. That will prevent that line also from appearing in your history.

I know this is an old thread. Just wanted to add this for completion:

If you just want specific commands not to be saved check if HISTCONTROL variable is set: HISTCONTROL=ignoreboth or HISTCONTROL=ignorespace

Every command that starts with a leading space will not be put in the history.

Just my 2 cents.

From: man bash

HISTCONTROL
A colon-separated list of values controlling how commands are saved on the
history list.  If the list of values includes ignorespace, lines which begin
with a space character are not saved in the history list.  A value of
ignoredups causes lines matching the previous history entry to not be saved.
A value of ignoreboth is shorthand for ignorespace and ignoredups.  A value
of erasedups causes all previous lines matching the current line to be
removed from the history list before that line is saved.  Any value not in
the above list is ignored.  If HISTCONTROL is unset, or does not include a
valid value, all lines read by the shell parser are saved on the history
list, subject to the value of HISTIGNORE.  The second and subsequent lines
of a multi-line compound command are not tested, and are added to the
history regardless of the value of HISTCONTROL.


Here is your bash history toolkit...

Exit bash without writing anything

kill -9 $$

This is hacky and aggressive. But it's a fun way to end an espionage session.

Clear history from memory

history -c

This clears memory of all history. If you hit the up arrow, you get nothing. Your $HISTFILE is untouched. You can prove this with...

Reload history from disk

history -r

This rereads the $HISTFILE and appends it to the history in memory (if there is any). You can do this after history -c to regain the ability to Ctrl+R search or up arrow for previous commands. (You can do this instead of logging out and back in).

Note: If you didn't clear history first, this just appends to the current history in memory. This will obscure the history so that hitting the up arrow a few times will give you comfort in thinking that what you wanted to hide is gone. In reality it is just buried and will be written to disk unless it is deeper than your $HISTSIZE or $HISTFILESIZE.

Execute a command without including it in history

See th3penguinwhisperer's answer for the "set an option to have bash not record commands that are prefixed with a space" solution. I omit that (and the ignoredups and erasedups) from my list because I think bash history should be journal and not a search index.

echo foo bar baz; history -d $(history 1)

This uses history -d to delete an entry by number. Since only the first argument is used (and others are ignored) we can use the output of history 1 (which is identical to history | tail -n 1) to get the number of the current entry.

Because bash oneliners are single history entries, you can do multiple commands like so:

echo foo; echo bar; echo baz; history -d $(history 1)

This also works:

echo foo \
bar \
baz; history -d $(history 1)

Even this works:

for x in foo bar baz; do
echo $x
done; history -d $(history 1)

Delete your password (a command, etc.) from your history

If all you are concerned about is getting rid of a single entry, you can use the previous example creatively. Use history to find the number of the entry to delete. Then delete it by number. For example...

$ history
1  pwd
2  date
3  sudovisudo
4  hunter2
5  man history
6  help history
7  history
$ history -d 4

I hope I don't have to tell you this, but just in case: Don't grep history for your password. If you "really do" need to search history, do history | LESSHISTFILE=/dev/null less, and explicitly do a / search.

If you are really embarrassed and want there to be no record of you deleting something from history, you can combined this concept with the last.

history -d 4; history -d $(history 1)

Or to also get rid of the original mistake...

for n in "$(history 1)" 4 3; do history -d $n; done

Notice that you have to cycle over the entry numbers in decending order because each call to history -d pops the entry out of the list and all subsequent entries' numbers decrease by 1. Also, you have to double quote the subshell because history 1 returns not just the number, but also the command and its arguments, and each would get a separate cycle in the for loop. But at this point this is turning into a bash lesson and I'll stop.