11

I am writing a simple script to grep my bash history to find a particular string. On the command line, I can do the following, which works fine:

history | grep git

However, when I create a bash script with the same command as above, suddenly history returns nothing:

#!/bin/bash
history | grep git

When I remove the first line #!/bin/bash, my script works again. What is happening here? How can I use history inside a bash script?

2 Answers 2

15

When you run a bash shell script, for example by running an executable file whose shebang line is #!/bin/bash, the script is run in a non-interactive shell. One of the features of a non-interactive shell is that history is disabled. So if you want your script to be able to use history, you'd need to do something like this:

#!/bin/bash
HISTFILE=~/.bash_history   # Or wherever you bash history file lives
set -o history             # enable history
history | grep git

Of course, in this case you could have just done:

grep git ~/.bash_history

Since both of the above require that the history file (~/.bash_history) be up to date, which it almost certainly will not be.

I'm not sure how you run your script after the shebang line is removed. Sourcing the file (eg., with .) is not the same as running the script because the commands run in the current shell, which does have history enabled.

2
  • What about doing history -a right after the set command to make sure the last commands are appended to the file first?
    – user44370
    Feb 3, 2014 at 22:16
  • 4
    @illuminÉ: won't help. The shell started to run the script is a completely diffetent process; it starts with a frsh empty history.
    – rici
    Feb 3, 2014 at 22:26
9

The following is for bash 4.0 or higher only, but it does the trick. :)

#!/bin/bash -i
history | grep sometext

Works! Try it out. (-i = interactive, a flag not available to bash 3.x and earlier)

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .