Our small company runs an Ubuntu Server 11.10, to which a couple of people have SSH access. The actual terminals are sometimes used, too. How can we locally log all Bash commands run, along with user and time stamp?

We can assume that no-one is nefarious and actively trying to avoid the logging, but we'd still prefer the users not to have direct write-access to their log files. Simultaneous sessions must be handled correctly.

up vote 28 down vote accepted

For BASH shells, edit the system-wide BASH runtime config file:

sudo -e /etc/bash.bashrc

Append to the end of that file:

export PROMPT_COMMAND='RETRN_VAL=$?;logger -p local6.debug "$(whoami) [$$]: $(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//" ) [$RETRN_VAL]"'

Set up logging for "local6" with a new file:

sudo -e /etc/rsyslog.d/bash.conf

And the contents...

local6.*    /var/log/commands.log

Restart rsyslog:

sudo service rsyslog restart

Log out. Log in. Voila!

But I forgot about log rotation:

sudo -e /etc/logrotate.d/rsyslog

There is a list of log files to rotate the same way...


So add the new bash-commands log file in that list:



  • Forgot about log rotation which I added to the answer. – user8290 Jan 7 '12 at 16:13
  • 1
    This way works, but I could invent a method around it (with csh, .bash_logout perhaps). I would go with Sabacon's acct solution. These were excellent reads: linuxjournal.com/article/6144 and beginlinux.com/blog/2010/01/… – user8290 Jan 8 '12 at 2:19
  • 2
    I believe this can be easily deactivated by the user by simply resetting or unsetting PROMPT_COMMAND or exec-ing to a non-bash shell. – Stefan Lasiewski Dec 9 '13 at 18:19
  • Is there anything special about local6? What does it refer to? – Benubird Feb 25 '14 at 11:26
  • @Benubird it looks like there's a few preset facility levels, 8 of them being local0-local7: en.wikipedia.org/wiki/Syslog . 0 means emergency, 7 means debug, and 6 is just shy of 7, "normal operational messages." – munchybunch May 16 '14 at 5:16

A process accounting system may be helpful in this regard, particularly the acct package that provides the lastcomm and ac commands.

The ac commands prints out statistics about users' connection time, in hours. This is the amount of time that the user has been connected to the system, either remotely via SSH or a serial terminal, or while on the console.

The lastcomm command displays information about the previously executed commands. The most recent entries are given at the top of the list. Also displayed is the total amount of CPU time that each process used.

An old tutorial that may be helpful is here:


Other accounting commands like last and so on can be found in this tutorial:


  • lastcomm is pretty pointless as a command logger. It only records the executable that was run. No arguments, switches or paths are logged. – Phil_1984_ Oct 15 '16 at 19:25

You can find here a script to log all bash commands/built-ins into a text-file or a syslog server without using a patch or a special executable tool.

Very easy to deploy, as it is a simple shell script that need to be called once at the initialization of the bash.

It is free and I hope it suit your needs.

  • 1
    This is a good answer but it's preferable to include the steps and the script in the body of the answer, instead of linking to your blog. Can you please edit your answer to include this? – Tom Brossman Sep 22 '12 at 16:28
  • 2
    Site now unavailable – Gaia May 12 at 18:47

You could use snoopy.

Snoopy logger may suit your purpose well. It is not intended to be unavoidable logging solution, but rather a helpful tool for diligent admins who prefer to keep track of their own actions.

Disclosure: I am snoopy maintainer.

  • Please provide instructions on installing and using it in the answer. – muru Nov 6 '14 at 0:45
  • 1
    Detailed installation instructions are available on the snoopy github page, which is the main snoopy resource right now: github.com/a2o/snoopy. I am agains providing installation instructions in other places as primary location is maintained by design and others are not. BTW Readme was just updated to be more structured. – Bostjan Skufca Nov 6 '14 at 1:31
  • 1
    Maybe so. But without even a summary of the steps needed to use this, this is a link-only answer and likely to be deleted. – muru Nov 6 '14 at 1:35
  • 1
    Well, I provided a pointer to an alternative and viable solution. If that is not what this site is all about, then by all means it should get deleted, together with my account. – Bostjan Skufca Nov 6 '14 at 1:38
  • 2
    @BostjanSkufca no need to be offended. It's just a Stack Exchange thing to have at least reasonably self-contained answers. If you're so strongly opposed to adding steps, that's your wish. My downvote remains. Someone will probably upvote it. – muru Nov 6 '14 at 1:52

To take care of multiple sessions not over-writing the history file, you will have to put "shopt -s histappend" in a Bash startup file. See, also this question on the same problem.

try this (the solutions above will not work 100% with bash 4.3):

export HISTTIMEFORMAT="%Y-%m-%d %T "
export PROMPT_COMMAND='trap "" 1 2 15; history -a >(tee -a ~/.bash_history | while read line; do if [[ $line =~ ^#[0-9]*$ ]]; then continue; fi; logger -p user.info -t "bash[$$]" "($USER) $line"; done); trap 1 2 15;'

this does the logging AND it prevents logging of timestamps that are used for the bash history file. the trap is needed, since bash will send the signals to the "subjob" after pressing strg+c multiple times (tested with bash 4.3). this will force the logout of the current user (e.g. logged in with sudo)

You can also try installing acct. Acct keeps a detailed audit trail of what’s being done on your Linux systems.

sudo apt-get install acct

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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