Ubuntu – Why isn’t this script to delete part of the command history working on the computer

bashcommand linescripts

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.

Best Answer

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.

Related Question