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.

6 Answers 6


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:



  • 1
    Forgot about log rotation which I added to the answer.
    – user8290
    Jan 7, 2012 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, 2012 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. Dec 9, 2013 at 18:19
  • 1
    @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." May 16, 2014 at 5:16
  • 1
    @yukashima because logs can become big files if not deleted, rotating means to rotate the log files and delet the older ones to keep logs smaller... Jun 13, 2019 at 1:02

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, 2014 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. Nov 6, 2014 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, 2014 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. Nov 6, 2014 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, 2014 at 1:52

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:


  • 1
    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, 2016 at 19:25
  • lastcomm logs a lot of garbage. I see endless lists of "df, tail, head, sleep, who" commands that nobody run.
    – xtian
    Sep 5, 2022 at 14:03

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

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 must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .