1

The requirement is to capture command line history in a file with specific date and time of commands, when they were executed.

The below script captures history with date and time but it also assigns the current date and time for older commands. Also I want to extend the script to take incremental backup of the history output file.

#!/bin/bash
. ~/.bash_profile
HISTFILE=~/.bash_history
set -o history
history >/home/user/hist_`date "+%d%b%y%T"`
  • Don't use shell history for this. Use accounting or sudo (and log sudo commands). – lcd047 Jul 7 '15 at 6:06
  • How to use accounting or sudo for history capture in a file – SunLynx Jul 15 '15 at 11:07
  • sudo can be configured to capture its history (and even tty output) into a file (or via syslog). What do you mean by "accounting"? – Otheus Jul 23 '15 at 16:33
  • @SunLynx, see How can you log every command typed – Evgeny Vereshchagin Jul 28 '15 at 22:18
4

Not quite what you wanted, but you can get bash to add timestamps to each line in the history automatically. Simply set, for your example:

HISTTIMEFORMAT="%d%b%y%T "

The history command with no arguments will then show your history entries like this:

23Jul1515:48:14 ls -ld .

The history -w command however always writes the history file in the internal format of:

#1437659315
ls -ld .

i.e. on 2 lines, the first line holds the time in seconds "since the epoch" (i.e. 1 jan 1970) with a # in front so that it will not be confused with a command.

  • I want to capture history on daily basis, above script works but it assign current date to all commands. Also after every command one number generates, which I don't want. If anybody can help, that will be really helpful – SunLynx Jul 21 '15 at 13:40
  • I dont know what you mean by "one number generates". Could you edit your original question with an example of what files you want to get, and their contents? – meuh Jul 21 '15 at 14:17
  • 598 05Jul15 00:00:01less .bash_history 599 05Jul15 00:00:01#1435987168 600 05Jul15 00:00:01man rsync 601 05Jul15 00:00:01#1435988263 602 05Jul15 00:00:01ls -lrt /srv/cloud-* 603 05Jul15 00:00:01#1435988281 604 05Jul15 00:00:01crontab -l 605 05Jul15 00:00:01#1435988290 606 05Jul15 00:00:01cat /srv/cloud-user_hist.sh – SunLynx Jul 23 '15 at 13:24
  • like this messages generates – SunLynx Jul 23 '15 at 13:25
  • it is hard to read this in a comment. remove your comments and edit the question you originally wrote, please. – meuh Jul 23 '15 at 13:26
3

In bash, there is an option that instructs bash to record a timestamp with each command. You do this by assigning a useful value to the environment variable HISTTIMEFORMAT. From the bash manpage:

If this variable is set and not null, its value is used as a format string for strftime(3) to print the time stamp associated with each history entry displayed by the history builtin. If this variable is set, time stamps are written to the history file so they may be preserved across shell sessions. This uses the history comment character to distinguish timestamps from other history lines.

In my environment, I use

HISTTIMEFORMAT="%s (%H:%M:%S):"

So that the commands may be sorted easily (%s is timestamp in seconds) and human-readable. In my shell, when I type history, I see something like the following:

3  1437664568 (17:16:08):man bash
4  1437664699 (17:18:19):history

EDIT: OPs question not fully answered.

Also I want to extend the script to take incremental backup of the history output file

I'm not sure what you mean by "incremental backup" of the history file. Perhaps you simply want the history backed up periodically. There are a couple of approaches you can take:

  • Set PROMPT_COMMAND variable with history -a to continually update the history command after every invocation (as opposed to waiting for logout).
  • Trap the DEBUG signal with a function you define. Every time a command is entered, the function will be called. From within the function you can do everything. (Slightly more reliable than PROMPT_COMMAND).
  • cronjob to periodically copy/archive the history file.
  • Thanks for suggestions but I've tested above. Can you please elaborate more about history -a. Shell script is working fine but wrong time stamps. This is the one problem and another is one number after every command which starting with #. for e.g. #1435987168. – SunLynx Jul 24 '15 at 8:02
  • 1
    The #1435987168 in the history file is the timestamp! There are a couple of ways to convert that into user-friendly format, including: load the history file into bash with history -n _filename_ and then history. Or you can do something like this: perl -lane '{ /^#(\d+)$/&&print "#".localtime($1) or print;}' $HISTFILE to display the history with the timestamps. So it's probably that the timestamps are correct, but you have a locale or timezone problem? – Otheus Jul 24 '15 at 13:02
  • Elaborate on history -a?? The man page is a little misleading. It appends the current session history to the file designated by $HISTFILE. Subsequent calls will append the history generated since the last invocation (it doesn't overwrite the whole file over and over again) – Otheus Jul 24 '15 at 13:02

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.