The script can be found here: https://stackoverflow.com/questions/14750650/how-to-delete-history-of-last-10-commands-in-shell

For convenience here it is:

for x in `seq $1 $2`
do
  history -d $1
done

I put this in my include directory (one which I've added to the PATH) where I run many other scripts I've written and work just fine.

This does not produce the desired result of deleting rows from my history, in fact it does nothing at all.

Any idea why the history command doesn't work? I'm wondering if it has something to do with the directories.

Additional Info:

I played around with the code and tried different variations. If I put an echo in front of the history command and run it, I get the following output:

cgravel@scspc578:~$ idelhistory 300 305
history -d 300
history -d 301
history -d 302
history -d 303
history -d 304
history -d 305
cgravel@scspc578:~$ 

So, to me, it seems like it should work perfectly. I can't figure out why. This script is being run from /$HOME/Scripts/ and it has been included in the PATH. I also tried running it with sudo and nothing changes.

  • 2
    @John1024 If you read the comments on that answer the author of the post is very explicit that $1 is correct. – Seth Jan 12 '15 at 18:54
  • 1
    @Klik Try replacing the backticks (`) with a single quote ('). That resolved it for me. – RPi Awesomeness Jan 12 '15 at 19:07
  • 1
    @Klik Yeah, I got that same error - it would appear to be some form of error with the loop. – RPi Awesomeness Jan 12 '15 at 19:20
  • 1
    $1 is definitly wrong!! it has to be $x. you would try to remove the start number $x times. – LittleByBlue Jan 12 '15 at 19:30
  • 3
    @John1024 it is necessary that $1 be used in the for loop as the positional structure of history is not static, but is rather that of a vector. If you used $x, it would fail ~half-way through. – joshumax Jan 12 '15 at 20:42
up vote 10 down vote accepted

In one sentence: it doesn't work because you aren't calling it correctly.

First, since your script doesn't start with #!/bin/bash, it isn't actually a bash script. Which shell it is executed by depends on how you invoke it. When you invoke it from the bash command line, bash forks a new instance of itself (this has to happen to execute any external command anyway), and it's this new instance that executes the script. So the script is executed with the same settings (including the history so far) as the parent shell. It is executed with different options; in particular, history tracking is off for the commands in the script (which suits you, since otherwise it would add to the history that you want to modify).

Whether the bash instance executing the script has the HISTFILE variable set depends on whether it was exported in the parent (which is a little weird). If it isn't exported and thus set in the child, then the child script won't save the modified history when it ends.

If HISTFILE is exported, then the child script will modify your history file. However, unless you've configured your interactive shell to reload the history after every command, the modified history will only be picked up by newly started instances of bash.

If you want to run a shell snippet that affects the current shell instance, you must run that shell in the current shell instance, instead of running it as a subprocess. You'd run into a similar problem if you wanted to do other things that affect the shell process itself, such as changing directories, setting variables, etc. Use the . (“dot”) or source builtin to run a script in the current shell process.

. idelhistory 300 365

Alternatively, you could define this as a function in your .bashrc.

Edit: It seems that there still seem to be some problems on certain machines that run this script. Another (and perhaps the best) way of doing this would no be attempting to use a shell builtin, but rather directly modifying the $HISTFILE

#!/bin/bash
HISTFILE=~/.bash_history # Or just let the shell decide
for x in `seq $1 $2`
do
  sed "\'$1d\'" $HISTFILE
done

Original Answer:

The problem seems to be with running the bash script non-interactively...

This thread on Unix and Linux seems to cover a workaround method to get your script working:

#!/bin/bash
HISTFILE=~/.bash_history   # Or wherever you bash history file lives
set -o history             # enable history
for x in `seq $1 $2`
do
  history -d $1
done
  • 1
    You can also "run" your script in the current (interactive) shell by using source or the bash builtin . like so: source script.sh line1 line2 or . script.sh line1 line2. – Seth Jan 12 '15 at 21:02
  • I copied and pasted. I tried changing quotes. I tried switching which number was greater. I tripled checked permissions. I'm not getting a positive result. – Klik Jan 12 '15 at 21:11
  • @Klik Hmm, yeah, it isn't working for me either, although my comment above works. – Seth Jan 12 '15 at 21:24
  • Yes, Seth your solution works for me source idelhistory3 350 400 . Perhaps that should be the solution for this thread. – Klik Jan 12 '15 at 21:50
  • @Klik Check the edit. Does that work? – Seth Jan 12 '15 at 22:45

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.