First of all, note that your history is already in a file. If you're running bash, its name is usually ~/.bash_history
. More specifically, it is whatever you have set the variable HISTFILE
to. If you want to copy it to another file, just run cat "$HISTFILE" > hist.txt
Now, as to why the history
command doesn't work in a bash shell script, that's because scripts are run in a non-interactive child shell of your current shell session. Child shells don't inherit all of the parent's environment (so not all of the set variables), only the variables that have been exported. To illustrate, the script below will echo the value of the variable $var
:
#!/bin/bash
echo "$var"
Now, set $var
to something and run the script:
$ var="foo"
$ foo.sh
VAR:
Next, export the variable first:
$ var="foo"
$ export var
$ foo.sh
VAR: foo
As you can see, when the variable has been exported, it is available to child shells.
As I mentioned before, the history is stored in the file pointed to by the variable $HISTFILENAME
. Because that isn't exported by default, it is not set when running a script:
$ cat foo.sh
#!/bin/bash
echo "HISTFILE: $HISTFILE"
$ ./foo.sh
HISTFILE:
$ echo $HISTFILE
/home/terdon/.bash_history
As you can see in the example above, the variable HISTFILE
is set in my normal shell session, but is empty when running the script.
So, to get the history, you have a few options:
The the default HISTFILE
value is $HOME/.bash_history
. If you haven't changed that, you can simply run this command in your script:
cat "$HOME/.bash_history" > history
You can pass the $HISTFILE
variable to your script and cat
that:
#!/bin/bash
cat "$1" > history
Save the above as foo.sh
and run like this:
./foo.sh "$HISTORY"
Make sure the variable is exported. Add this line to your ~/.bash_profile
(if it exists) or ~/.profile
(if ~/.bash_profile
doesn't exist) files:
export HISTFILE
Then, log out and log back in again and you should be able to run history > hist.txt
from a script as expected. This is because export VAR
means "make $VAR available to child shells". In practical terms, this means that the value of HISTFILE
will be inherited by the non-interactive shell you use to run your script.
Now, while the HISTFILE
will be set, it hasn't been read by the shell running the script. So, to get it to work, you'd need to read it with history -r
first. The whole script would look like this:
$!/bin/bash
history -r
history > hist.txt
Alternatively, just export it manually before running the script:
$ export HISTFILE
But you'll still need to history -r
in the script.
You can source
it as suggested by @p0llard's answer.
~/.bash_history
file.