Thursday, April 12, 2012

How to log commands executed by all the users in Linux?

By adding the following entry in /etc/bashrc, we can log the commands executed by all the users on a Linux machine. 
This would be certainly helpful for tracking commands on Critical servers.

PROMPT_COMMAND='history -a >(logger -t "$USER[$PWD] $SSH_CONNECTION")'

After you added the above entry at the end of /etc/bashrc file, execute the command 'source /etc/bashrc' or logout and login back to your session. Now the commands executed by all the users will be logged in /var/log/messages.
Note: If you wish to log the commands on to a different file, please check the solution given in the comments section.

Sample test result:

Apr 18 13:35:21 Linux-Mach root[/root] 51650 22: uptime
Apr 18 13:35:24 Linux-Mach root[/opt] 51650 22: cd /opt
Apr 18 13:35:26 Linux-Mach root[/opt] 51650 22: ls -lR
Apr 18 13:35:35 Linux-Mach root[/opt] 51650 22: iostat -x 2
Apr 18 13:35:39 Linux-Mach root[/root] 51650 22: cd /root
Apr 18 13:35:39 Linux-Mach root[/root] 51650 22: ls -l
Apr 18 13:35:51 Linux-Mach root[/home] 51650 22: cd /home
Apr 18 13:35:52 Linux-Mach root[/home] 51650 22: ls
Apr 18 13:35:56 Linux-Mach root[/home] 51650 22: httpd -t

Apr 18 13:51:24 Linux-Mach test1[/home/test1] 9106 22: ls -l
Apr 18 13:53:20 Linux-Mach test1[/var/lock/subsys] 9106 22: cd /var/lock/subsys
Apr 18 13:53:30 Linux-Mach test1[/var/lock/subsys] 9106 22: ls -ltr


  1. This was an excellent one, is their any option to store the command in different location instead of /var/log/message

  2. Hi Siva, Good question. It should be possible by adjusting the Syslog facility. I will come out with a solution soon.

  3. Hi Siva, Here's the solution for you to log the commands on to different file.

    Lets say you want to capture the command execution in a different file called "/var/log/usercommands".

    Open the /etc/syslog.conf file and insert the syslog facility entry (local[0-6].info) as shown below:

    *.info;mail.none;authpriv.none;cron.none /var/log/messages /var/log/usercommands

    (Please note that you can use the Syslog facility "local0-6" for any purpose)

    After this, restart the 'syslog' service.

    Update the entry in /etc/bashrc as follows:
    PROMPT_COMMAND='history -a >(logger -p -t "$USER[$PWD] $SSH_CONNECTION")'

    Run 'source /etc/bashrc'

    Now all the commands will be captured in /var/log/usercommands.

    Note: Using '-p' with logger command, we can redirect the logs to a different Facility with different priority defined in /etc/syslog.conf file.

    More details on Syslog facilities and priorities:

  4. Thankyou for providing the solution

  5. By making the variable "readonly" the end user cannot change it and conceal their actions.

    readonly PROMPT_COMMAND='history -a >(logger -t "$USER[$PWD] $SSH_CONNECTION")'
    readonly PROMPT_COMMAND='history -a >(logger -p -t "$USER[$PWD] $SSH_CONNECTION")'

  6. Wow...that was an Excellent tip Jason !! Thankyou so much !!

  7. Guys, I'm getting the following error while running "source /etc/bashrc" command. Please help me out the resolution for this.

    /root# source /etc/bashrc
    -sh: PROMPT_COMMAND: line 5: syntax error near unexpected token `('
    -sh: PROMPT_COMMAND: line 5: `history -a >(logger -t "$USER[$PWD] $SSH_CONNECTION")'
    (**root**on usclswups011)

  8. This comment has been removed by the author.

  9. @Basha, This is a Syntax error in /etc/bashrc file. It appears you are using a Back tick (`) instead of single-quote (') infront of "history -a". Please correct that and try.

  10. Hi Ashok,

    Is there a way to transmit the user issue command to another server for instance a centralized logging server?

    1. Yes, there is.

      You just have to selectively ship a certain type of logs to a remote server. For ex, in rsyslog to ship all logs over UDP, you do something like:


      You just need to replace *.* with more specific priority.

  11. Yes, you can push the logs to Centralized Log server.


  12. This comment has been removed by a blog administrator.

  13. This comment has been removed by the author.

  14. But this is not working for normal users

  15. Hi Ashok, great tutorial! just one thing, this is not logging any user commands, it's logging just root commands. Is it possible to log in ALL users' commands? Thanks!!

  16. In your bashrc if you put in a variable
    WHOIAM=l`who mom likes | awk '{print $1}'
    then put the variable in your
    readonly PROMPT_COMMAND='history -a >(logger -p -t "$WHOIAM:$USER[$PWD] $SSH_CONNECTION")'

    This way you will also log on one line if someone SU's to someone else. So if someone SU's to root you will see the commands as root and also be able to tell the origination user

  17. whoops.. type
    WHOIAM=l`who mom likes | awk '{print $1}'
    should read
    WHOIAM=`who mom likes | awk '{print $1}'

  18. You could use snoopy:

  19. Hi Ashok,
    I keep getting
    -bash: PROMPT_COMMAND: readonly variable

    Pls help

    1. do an "unset -f PROMPT_COMMAND". Then login via another session and run "source /etc/bashrc". It worked for me

  20. Hi Ashok,

    Thanks for nice guide, It's working as excepted,

    My case, I am exec. command and different machine, Not same machine, When I login the particular server executing some command means it's recording nicely.

    In my case ::
    I am executing 'df -H' command from different not recording.

    ssh sysops@ 'df -H'

    Please guide me.

  21. I see the logs duplicated in "messages" file and also "usercommands" file. Is it possible to save the logs only in "usercommands" file and not is messages?