{"id":728,"date":"2008-07-31T19:16:09","date_gmt":"2008-07-31T18:16:09","guid":{"rendered":"http:\/\/www.zarrelli.org\/blog\/?p=728"},"modified":"2008-07-31T19:17:25","modified_gmt":"2008-07-31T18:17:25","slug":"history-time-format","status":"publish","type":"post","link":"https:\/\/www.zarrelli.org\/blog\/history-time-format\/","title":{"rendered":"History Time Format"},"content":{"rendered":"<p>Did you ever had a look at you bash history?<\/p>\n<p>No? Well, try it issuing the following command:<\/p>\n<pre>root@moveaway: history<\/pre>\n<pre>...\r\n996  netstat -tapn\r\n997  vi \/etc\/my.cnf\r\n998  vi \/etc\/my.cnf\r\n999  service mysql restart\r\n1000  service mysqld restart\r\n1001  history<\/pre>\n<p>Wow! One thousand (and one) commands issued on my laptop command line! Nice, insn&#8217;t it?<\/p>\n<p>Well, ohhhh yess&#8230;but&#8230;mmm&#8230;when did I issue each command?<\/p>\n<p>The default behaviour for the bash history file (.bash_history in your home directory), is to take note <strong>only<\/strong> of the commands, nothing else, as you can see &#8220;catting&#8221; the raw file:<\/p>\n<pre>root@moveaway: cat .bash_history\r\n..\r\nnetstat -tapn\r\nvi \/etc\/my.cnf\r\nvi \/etc\/my.cnf\r\nservice mysql restart\r\nservice mysqld restart<\/pre>\n<p>Not that useful if you are trying to link some correlations from the commands you issued and what happened in your system. Better for you to timestamp you history log.<\/p>\n<p>How to do it?<\/p>\n<p>First, let&#8217;s pay attention to what<\/p>\n<pre>root@moveaway: man bash<\/pre>\n<p>tells us:<\/p>\n<blockquote><p><strong>HISTTIMEFORMAT<\/strong><br \/>\nIf  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 his-<br \/>\ntory entry displayed by the history builtin.  If this variable is set, time stamps are written to the history file so they may  be  preserved<br \/>\nacross shell sessions.<\/p><\/blockquote>\n<p>So, setting the variable<\/p>\n<pre>HISTTIMEFORMAT<\/pre>\n<p>would give a relief to our concern. The syntax is similar the one you use for the command<\/p>\n<pre>date<\/pre>\n<p>so<\/p>\n<pre>man date<\/pre>\n<p>will help you to find a proper format string for this variable. Anyway, if you have no idea, here is a pre formatted variable (Year-Month-Day Hours:Minutes:Seconds)<\/p>\n<pre>HISTTIMEFORMAT=\"%Y-%m-%d %H:%M:%S \"<\/pre>\n<p>This string alone won&#8217;t work, we have to &#8220;export&#8221; it as a environment variable:<\/p>\n<pre>export HISTTIMEFORMAT=\"%Y-%m-%d %H:%M:%S \"<\/pre>\n<p>Mmm&#8230;let&#8217;s have a look to our history:<\/p>\n<pre>root@moveaway: history<\/pre>\n<pre>997  2008-07-31 19:40:34 vi \/etc\/my.cnf\r\n998  2008-07-31 19:40:34 vi \/etc\/my.cnf\r\n999  2008-07-31 19:40:34 service mysql restart\r\n1000  2008-07-31 19:40:34 service mysqld restart\r\n1001  2008-07-31 19:40:37 history<\/pre>\n<p>Ouch! All the entries have the same date stamp! Well, to fix this we should exit the login session and logon again, but our environment variable would get lost. We must make it lasting through sessions. Let&#8217;s invoke the<\/p>\n<pre>man bash<\/pre>\n<p>command again:<\/p>\n<blockquote><p>When bash is invoked as an interactive login shell, or as a non-interactive shell with the &#8211;login option, it first reads and executes commands from<br \/>\nthe  file  \/etc\/profile,  if that file exists.  After reading that file, it looks for ~\/.bash_profile, ~\/.bash_login, and ~\/.profile, in that order,<br \/>\nand reads and executes commands from the first one that exists and is readable.<\/p><\/blockquote>\n<p>Interesting. It&#8217;s time to edit the<\/p>\n<pre>\/etc\/profile<\/pre>\n<p>file and write the command in, to make it last:<\/p>\n<pre>export HISTTIMEFORMAT=\"%Y-%m-%d %H:%M:%S \"<\/pre>\n<p>Save the file, exit the login session and logon again. Now issue some commands&#8230;<\/p>\n<pre>root@moveaway: prova_time_stamp_1\r\n-bash: prova_time_stamp_1: command not found\r\nroot@moveaway: prova_time_stamp_2\r\n-bash: prova_time_stamp_2: command not found\r\nroot@moveaway: prova_time_stamp_3\r\n-bash: prova_time_stamp_3: command not found\r\nroot@moveaway: history<\/pre>\n<p>Well, not real commands, but they will be a good placeholder to mark the timestamps. Let&#8217;s issue<\/p>\n<pre>history<\/pre>\n<p>again:<\/p>\n<pre>1001  2008-07-31 19:42:46 prova_time_stamp_1\r\n1002  2008-07-31 19:42:54 prova_time_stamp_2\r\n1003  2008-07-31 19:43:00 prova_time_stamp_3\r\n1004  2008-07-31 19:43:25 history<\/pre>\n<p>It works! Now our history is marked with a time stamp for each entry, so it will be easier to understand when a command has been issued. Let&#8217;s have a look to the<\/p>\n<pre>.bash_history<\/pre>\n<p>file, but since the file is fully written only <strong>after<\/strong> the login session is closed, logoff, logon again and then issue:<\/p>\n<pre>root@moveaway: cat .bash_history\r\n...\r\n#1217533366\r\nprova_time_stamp_1\r\n#1217533374\r\nprova_time_stamp_2\r\n#1217533366\r\nprova_time_stamp_3\r\n#1217533405\r\nhistory<\/pre>\n<p>What&#8217;s that? Each command is prefixed by a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Unix_time\" target=\"_blank\">Unix Timestamp<\/a>, which is converted for you by the<\/p>\n<pre>history<\/pre>\n<p>command, otherwise you can use an <a href=\"http:\/\/www.timestampgenerator.com\" target=\"_blank\">online converter<\/a>.<\/p>\n<p>Good, isn&#8217;t it?<\/p>\n<p>2 Cent Tip:<\/p>\n<p>If you want your history file to take note of more than the standard 500 commands, put in the<\/p>\n<pre>profile<\/pre>\n<p>the following string:<\/p>\n<pre>export HISTSIZE=1000<\/pre>\n<p>You will have a 1000 commands worth history file.<\/p>\n<p>Second 2 Cent Tip:<\/p>\n<p>If you want more infos on the time syntax for<\/p>\n<pre>HISTTIMEFORMAT<\/pre>\n<p>have a look to<\/p>\n<pre>man 3 strftime<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Did you ever had a look at you bash history? No? Well, try it issuing the following command: root@moveaway: history &#8230; 996 netstat -tapn 997 vi \/etc\/my.cnf 998 vi \/etc\/my.cnf 999 service mysql restart 1000 service mysqld restart 1001 history Wow! One thousand (and one) commands issued on my laptop command line! Nice, insn&#8217;t it? &hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[31,57,62],"tags":[278],"class_list":{"0":"post-728","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"hentry","6":"category-gnulinux","7":"category-sicurezza","8":"category-sysadmin","9":"tag-sysadmin-bash-history-audit-linux-gnulinux","11":"without-featured-image"},"_links":{"self":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/posts\/728","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/comments?post=728"}],"version-history":[{"count":0,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/posts\/728\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/media?parent=728"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/categories?post=728"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zarrelli.org\/blog\/wp-json\/wp\/v2\/tags?post=728"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}