1

I've seen a lot of documentation on how to timestamp the output of the history command. But how would you go about time-stamping a saved history file? For example I have a server setup to save each users bash history to /root/history/.bash_history-$USER. This is done through a line in /root/.bash_profile

export HISTFILE=/root/history/.bash_hist-$(who -m | awk '{print $1}')

I have added the line:

export HISTTIMEFORMAT="%d/%m/%y %T "

to /root/.bash_profile and sourced it. However timestamps are not put in the files, you only see them when you run the history command. How can I set this up to do both?

EDIT:

I have added the lines in my .bashrc file as suggested:

export HISTSIZE=3000
export HISTFILESIZE=5000
export HISTFILE=/root/history/.bash_hist-$(who -m | awk '{print   $1}')
format_history () {
 perl -i -e '$/=undef;my $string=<>;$string=~s/#([0-9]  {10}.*\n.*$)/"# ".localtime($1)."#\n#$1"/ge;print $string;'    /root/history/.bash_hist-$(who -m | awk '{print $1}')
}
export HISTTIMEFORMAT="%d/%m/%y %T "
shopt -s histappend
PROMPT_COMMAND="history -a;format_history;$PROMPT_COMMAND"

Now when I try to open my history file, using vim, cat or less, I see:

command I ran
#Thu Mar Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed Dec Wed     Dec Wed Dec Wed Dec Wed Dec 31 18:00:31 1969 18:00:31 1969 18:00:31 1969   18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969  18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 18:00:31 1969 14:26:02 2016

EDIT 3:

After making latest changes:

# Fri Apr  1 15:26:35 2016#
# Fri Apr  1 15:26:35 2016#
# Fri Apr  1 15:26:35 2016#
# Fri Apr  1 15:26:35 2016#
# Fri Apr  1 15:26:35 2016#
# Fri Apr  1 15:26:35 2016#
# Fri Apr  1 15:26:35 2016#
#1459542395
command
  • gnu.org/software/bash/manual/…: "If the HISTTIMEFORMAT is set, the time stamp information associated with each history entry is written to the history file, marked with the history comment character. When the history file is read, lines beginning with the history comment character followed immediately by a digit are interpreted as timestamps for the previous history line." – Jeff Schaller Mar 31 '16 at 16:30
  • I see the interpretation, it looks like this: #1459441117 less /var/log/maillog in the file. However I was wondering if there was a way to see the actual timestamp when viewing the file, and not just seeing it when running the command. – user53029 Mar 31 '16 at 17:36
  • that looks suspiciously like "number of seconds since the epoch" to me – Jeff Schaller Mar 31 '16 at 17:40
2

You could do something like

perl -Mposix -pe 's/^#([0-9]{10})/POSIX::strftime( "%d\/%m\/%y %T", gmtime($1))/eg' .bash_history > readable_history

to replace the epoch timestamps in the file with formatted ones. To do it in place, you could modify it to insert the formatted times as comments above each line, but make sure to put a space before the first number so that bash doesn't try to interpret it as it's own timestamp when reading the history file.

Edit: Here's the line to do it in place without messing up the history file:

perl -Mposix -i -pe 's/^#([0-9]{10})(.*)/"# ".POSIX::strftime( "%d\/%m\/%y %T", gmtime($1))."\n#$1$2"/ge' .bash_history

This will make a file that looks like this:

#1356431101 command arg arg
#1356531101 command2 arg2

Look like this:

# 25/12/12 10:25:01
#1356431101 command arg arg
# 26/12/12 14:11:41
#1356531101 command2 arg2

Edit2: Putting this in my bashrc did the trick for me:

format_history () {
    perl -i -e '$/=undef;my $string=<>;$string=~s/#([0-9]{10}.*\n.*$)/"# ".localtime($1)."#\n#$1"/ge;print $string;' ~/.bash_history
}
export HISTTIMEFORMAT="%d/%m/%y %T "
shopt -s histappend
PROMPT_COMMAND="history -a;format_history;$PROMPT_COMMAND"

Final edit -- Here's a better version of the regex that shouldn't duplicate anything:

perl -i -e '$/=undef;my $string=<>;$string=~s/(#\s[^\n]*\n)?#(\d{10}\n)/"# ".localtime($+)."\n#$+"/ge;print $string;' your_history_file_name_here
  • Comments are not for extended discussion; this conversation has been moved to chat. – terdon Apr 2 '16 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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