152
46
How can I remove a certain line from history
's database?
152
46
How can I remove a certain line from history
's database?
118
You need to log out and back in or run history -a
so the current history is committed to disk.
Then just edit the file ~/.bash_history
.
152
You can achieve removal from the history file using the commandline in two steps:
history -d <line_number>
deletes a specified line from the history in memory.history -w
writes the current in-memory history to the ~/.bash_history
file.The two steps together remove the line permanently from the in-memory history and from the .bash_history file as well.
7how to delete the last history -w
from history? – KrIsHnA – 2015-03-05T09:01:45.537
@KrIsHnA edit ~/.bash_history manually – Alexander Myshov – 2015-05-23T06:51:18.567
5Or add a space before it to prevent it from being added, as in @tao's answer – Mark – 2015-08-18T08:28:47.620
To find <line_number>
just history | grep [unwanted_content]
to get a list with all the lines containing [unwanted_content]
(like passwords). – AvL – 2017-09-18T15:23:07.973
How do you delete multiple (specific) lines (by id) ? – Pathros – 2018-06-19T17:38:12.933
You saved me and my bash history – Jacob S.P. – 2019-09-14T04:57:55.537
41
To prevent a command from being added to the history in the first place, make sure that the environment variable HISTCONTROL
contains among its colon-separated values the value ignorespace
, for example (add e.g. to .bashrc
):
$ export HISTCONTROL=ignorespace
This will prevent any command with a leading space from being added to the history. You can then clear the history completely by running
$ history -c -w
^-- additional space character
33
First of all, if the command you're about to issue is sensitive, unsafe, or you just don't need it cluttering up your history, it is best/quickest to just prevent it from entering the history in the first place. Make sure that $HISTCONTROL
contains ignorespace
:
(bash)$ echo $HISTCONTROL
ignoredups:ignorespace
Then proceed any command you don't want in your history with a space:
(bash)$ sensitive-cmd-with --password 82cf7dfe
(bash)$ rm -r... # One-off recursive remove; mustn't be accidentally repeated!
If you accidentally put an unwanted command into history, providing that your bash session is still open, the command hasn't yet touched the disk. To delete the previous command in history, issue:
(bash)$ history -d $((HISTCMD-1))
Note the leading space; this command requires ignorespace
, otherwise it'll just delete itself!
If you want to delete the last few commands, find the last and first history number:
(bash)$ history 5
598 ok
599 sensitive
600 unsafe
601 doesn\'t-work
602 otherwise-unwanted
In this case 602 and 599. Then issue:
(bash)$ for i in {602..599}; do history -d $i; done
(Without ignorespace
, it would be 603..599.)
If you don't want any history from your current session to hit the disk, exit using:
(bash)$ kill -9 $$
The approach so far is to not even let sensitive history items be written to disk for extra security, because in theory data deleted from non-volatile media can still be recovered.
If, however, the command(s) you wish to remove are from a previous session, they will have already been appended to the $HISTFILE
on exit. Manipulating the history with the above commands will still only append the remaining new items to the $HISTFILE
, on exit. To overwrite the $HISTFILE
with the current session's view of the entire history, right now, issue:
(bash)$ history -w
Of course for history items already on disk, the alternative to editing the history with history -d
commands then issuing history -w
, is to edit the $HISTFILE
with a text editor.
1”Manipulating the history with the above commands will still only append the remaining new items to the $HISTFILE
, on exit.” Actually, this isn't exactly true. It seems to only append remaining new items that ‘stick out’ from the original history length. E.g. If I remove 5 original items and add 15 new, only the last 10 new are appended, whereas I'd expect all 15 new to be appended. I think this is a bug because I can't see how this is ever desirable functionality. – James Haigh – 2013-06-19T15:59:35.367
1I guess bash takes note of the original length. On session close, it presumably appends items whose number is greater than this value. If this value was decremented every time an item is deleted whose number is less than or equal to this value, it would work as expected. ;-) – James Haigh – 2013-06-19T16:06:04.530
17
Several techniques:
If you've entered some password on a command line, then realize that all commands are logged, you could either:
Force exit the current session without saving history:
kill -9 $$
This will drop all current history.
Type ↑ (up arrow) in the open bash session until the sensitive information is shown, then use line editing keystrokes like Ctrl+W to delete the sensitive info, and then ↓ (down arrow) until a new empty line is prompted, before typing Enter.
If you realize that sensitive information is already stored, and you want to delete it, but not your entire history:
A simple sed
command could do the job:
sed -e '/SeNsItIvE InFo/d' -i .bash_history
but, as you type this, you create another history line containing the search pattern (sensitive info) you are trying to delete. So you could:
sed -e "/$(head -n1)/d" -i .bash_history
This will run head -n1
with input from the terminal.
It will appear that your terminal is hung (there won't be a prompt);
just type the information that you want to delete from the file.
This is a trick to let you enter (part of) a command
without actually typing it into the command line,
thus making it ineligible for inclusion in the history record.
Then sed
will use the text that you typed to search .bash_history
and delete all lines containing the sensitive info.
Note: if your sensitive information pattern contains slash(es),
you must escape them with backslashes,
or else change the sed
command to use this syntax
to specify a delimiter that does not appear in the pattern:
sed -e "\|$(head -n1)|d" -i .bash_history
Another way could be to delete only the sensitive info, but keep the commands that contain the information. For this, you could simply replace sensitive info with substitute text of your choice:
sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.
Finally, to be sure that this won't stay in another forgotten file:
SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"
will list all concerned files.
find . -type f -print0 |
xargs -0 grep -l "$SENSITIVEINFO" |
tr \\n \\0 |
xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i
will replace all occurrences of sensitive info in all files
in the directory tree rooted at .
.
Note: even though this command uses xargs -0
,
it will not handle files with newlines in their names.
Combining tricks from a related answer it should be possible to delete SeNsItIvE InFo
and the sed
command doing the deletion on the same line with something like sed -e '/SeNsItIvE InFo/d' -i .bash_history; history -d $((HISTCMD-1))
12
Locate the line you want to delete by pressing ↑ (up arrow) until it appears, then press Ctrl+U. That should remove the line.
If you use the history
command, you can see the line has been substituted with an asterisk.
2Actually, I believe that you must cursor up to the line, press Ctrl+U, and then cursor up or down to another line (possibly the blank one at the bottom of the list). Also, strictly speaking, the line hasn't been substituted with an asterisk. Rather, the command has been erased, and the history number has been appended with a *
. – G-Man Says 'Reinstate Monica' – 2015-04-01T16:47:50.623
2This becomes much more powerful with Ctrl+R (reverse incremental history search), then e.g. [End], Ctrl+U – sehe – 2015-06-15T12:13:34.583
5
If you need to remove several lines at the same time I normally use this:
history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'
If you need to remove the last command you can use:
history -d $((HISTCMD-2))
2This looked like it worked but history | grep <string>
still shows all the lines it claimed to delete... – Brock Hensley – 2013-04-19T00:09:12.030
1This will delete the wrong history lines after deleting the fisrt!! – mivk – 2013-12-20T14:51:07.957
1But fortunately, it only prints the wrong delete commands. The following would print the correct delete commands: history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
– mivk – 2013-12-20T15:17:18.703
3
If you need to remove a range of lines from history, the following bash function could save you some time:
function histdel() {
[ $# -eq 1 ] && history -d "$1" && history -w
if [ $# -eq 2 -a "$1" -le "$2" ]; then
for n in `seq "$2" "$1"`; do
history -d "$n"
done
history -w
fi
}
Function should be typically added to $HOME/.bashrc
. To use the function imediatelly, you will need to have the file read again by your running shell (. $HOME/.bashrc
). Then to delete e.g. commands 200-210 from history:
$ histdel 200 210
(Note: This question is among the top search results if you search for deleting a range of commands from bash history. So, while the above is more than what the question asks, it could be useful for some readers.)
3Alternative forms for the for
statement: for n in $(seq "$2" "$1")
is stylistically preferred by some, and, if seq
doesn’t work, try for ((n="$2"; n>="$1"; n--))
. – Scott – 2013-03-13T18:11:23.430
3
history | sed -i 59d
59 is the line number. Cannot be anything sweeter than this :)
3
Just try these,
$ history
this will display the id of the history and the command, e.g.
.
.
211 ls
212 javac Welcome.java
213 java welcome
.
.
use,
$ history -d 211
Here 211 is the id of the history. Now check this using
$ history
.
.
211 javac Welcome.java
212 java welcome
.
.
2
I know it's been a long time since this question has been asked and answered but I'll show you my method for cleaning my history file and logging out at the same time.
I run :
history -w && nano "${HISTFILE}" && history -c && exit
What it does is simple:
history -w
: writes cached history inside "${HISTFILE}"
nano "${HISTFILE}"
: allow me to edit "${HISTFILE}"
You could use a sed script or whatever your want to clean your "${HISTFILE}"
history -c
: clear cached history so this last command is not appended.exit
: log me out appending cached history... but it is empty ;)After that command, you'll be logged out with a clean history file. Log in to check your history ;)
I hope this will help someone.
1
You could also edit the history file directly, eg nano .bash_history
if you are in the bash shell?
3but how would you delete the record of editing the history file? – chiliNUT – 2014-07-23T19:54:11.237
5@chiliNUT: Just start your command (e.g.
vim ~/.bash_history
) with a space; commands starting with a space usually don't get logged (see$HISTCONTROL
). – cYrus – 2014-07-23T20:34:20.330I don't think thats the case in my distribution, but in general that makes sense – chiliNUT – 2014-07-23T22:29:44.453
Using
– F. Hauri – 2014-11-10T18:31:05.250sed
for doing this, instead of an handy editor ensure all occurence will be dropped! See my answerTo hide commands starting with a space (and also hide duplicate entries) from your bash history, put this in your .bashrc
HISTCONTROL=ignoreboth
– mason81 – 2015-06-12T06:58:30.267history -d
seems like a more correct approach. – jamesdlin – 2018-06-28T17:47:05.277history -a
first is what most other answers about this are missing, thank you. – felwithe – 2019-02-17T16:17:19.27720If the HISTFILE environment variable is set, the history file isn't ~/.bash_history but rather ${HISTFILE}. – Karolos – 2013-04-03T22:34:03.983
20Entries are written into the history file when you exit the shell. Therefore, after entering a command that you'd like to remove, you need to either log out and back in, or use 'history -d xxxx' to remove them from the current shell session. – harmic – 2014-01-24T00:19:02.947