Is it possible for the root user in Linux to have a real-time (or close to real-time) view of the shell commands being run by another user logged in via a terminal or SSH? Obviously they're stored in .bash_history, but that's only saved when the user logs off and can be disabled, too.

Edit: ideally something that can easily be switched on and off.


11 Answers 11


as root, you could replace their shell with a simple wrapper script that logged their commands before passing them to the real shell. This would only work prior to them logging in.

  • 22
    We did this to monitor a hacked account at a previous employer. Created "/bin/bash " (notice the space) that was a wrapper around the script-command. Worked like a charm :) May 16, 2009 at 6:23
  • Very clever! +1
    – EMP
    May 16, 2009 at 13:27

Use sniffy if you want to break into the user's session or screen -x if you have cooperation.

Be aware though, that spying on your users might be subject to regulations or even outright illegal depending on your local legislation.


Changing the shell is very trivial to circumvent, patching the shell itself is better, but you have to patch all shells. Our favourite cracker uses this, as a bonus he doesn't bother himself with disabling bash_history.

ssh host /bin/sh -i  

Snoopy is a wrapper around exec functions, and logs any external binary that is executed(not shell builtins)

@David Schmitt's suggestion sniffy uses a better method, it taps the pseudoterminal.

ttysnoop uses the same method, but it is unmaintained. (I probably had issues making it log ssh connections, can't rememeber)

You can try patching ssh to log a session, but that patch is old.

pseudopod and rootsh can be used for logging legitimate sudos. And shwatcr is another thing to monitor logins.

  • 1
    What exactly is ssh host /bin/sh -i supposed to do? Jun 6, 2012 at 11:59
  • +1 for snoopy, not perfect but did what we needed it to do.
    – skinp
    Jun 6, 2012 at 14:22

If you're being cooperative, you can use GNU screen between two users - have one establish the screen session, then have the other join using screen -x.

If you want root to "spy" on other users without their knowledge, the best and most efficient solution might be keylogger software/hardware.


Sysdig is powerful tool of system-level exploration - this is what you want ;)


sysdig -i spy_users

Category: Security

spy_users Display interactive user activity

lists every command that users launch interactively (e.g. from bash) and every directory users visit


You could try the bash-BOFH patch. Search around for the patch.


I wrote a method to log all 'bash' commands/builtins into a text-file or a 'syslog' server without using a patch or a special executable tool.

It is very easy to deploy, as it is a simple shellscript that need to be called once at the initialization of the 'bash'.

See the method here: http://blog.pointsoftware.ch/index.php/howto-bash-audit-command-logger

  • Welcome to Server Fault! We really do prefer that answers have content, not pointers to content. This ensures that the answer will remain available even if the link goes dead. Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
    – user9517
    Jun 6, 2012 at 11:32
  • Welcome to Server Fault! Please read our faq in particular May I promote products or websites I am affiliated with here?.
    – user9517
    Jun 6, 2012 at 11:33
function spy() { 
   ptsnum=`ps awfux | grep pt[s]\/"$1" | awk '/bas[h]/{print $2}'` ; 
   /usr/bin/strace -s 1000 -t -f -p $ptsnum 2>&1 3>&1 \
        | grep -Poi 'write\(...\"[[:print:]]{1,2}\"[.][.][.][,]..\)' ; 

[436] klikevil@epiphany ~ $ w<br>
 09:36:43 up 12:06,  6 users,  load average: 0.46, 0.29, 0.20<br>
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT<br>
klikevil pts/0     23:05    2:19m 10:33   0.18s cmd                                      <br>
klikevil pts/1     00:18    6:50m  0.06s  0.04s sshd: klikevil [priv]<br>
klikevil tty7     :0               09:02   17:07m  2:02   0.32s x-session-manager<br>
klikevil pts/2    :0.0             09:03    3:30   0.08s  0.08s bash<br>
klikevil pts/3    :0.0             09:03    0.00s  0.76s  0.00s w<br>
klikevil pts/4    :0.0             09:06    3:13   0.46s  0.00s /bin/sh /usr/bin/thunder<br>
[437] klikevil@epiphany ~ $ spy 2<br>
write(2, "e"..., 1)<br>
write(2, "c"..., 1)<br>
write(2, "h"..., 1)<br>
write(2, "o"..., 1)<br>
write(2, " "..., 1)<br>
write(2, "s"..., 1)<br>
write(2, "u"..., 1)<br>
write(2, "p"..., 1)<br>
write(2, " "..., 1)<br>
write(2, "d"..., 1)<br>
write(2, "o"..., 1)<br>
write(2, "g"..., 1)<br>
write(2, "\n"..., 1)<br>

Seems to work pretty well if you don't mind sorting through a bunch of line breaks.


Snoopy is intended for lightweight command logging.

If you want live view of commands executed on your system, this may be it. Warning: snoopy is not proper audit solution and can easily be circumvented.

However, if you desire to see every character typed into the terminal, then you will have to use another tool.

Disclosure: I am current snoopy maintainer.


Yes, it is possible with an open source tool called SSHLog (https://github.com/sshlog/agent). I am a contributor for this project.

You could install it natively as a daemon (and turn on/off the service), or run it as a Docker container when you want to use it. Docker seems closer to what you want (use this thing on-demand). To start the docker container, run:

docker run -d --name sshlog \
       --privileged \
       -v /sys:/sys:ro \
       -v /dev:/dev \
       -v /proc:/proc \
       -v /etc/passwd:/etc/passwd:ro \
       -v /var/log/sshlog:/var/log/sshlog \
       -v /etc/sshlog:/etc/sshlog \
       --pid=host \

Next, query the logged in users with:

docker exec sshlog sshlog sessions
 User        Last Activity        Last Command           Session Start               Client IP            TTY        
jdoe           just now                              2023-04-17 23:11:28         8      
bobj          2 hours ago                            2023-04-16 23:11:28         15   

Now you can share the terminal or just watch read-only mode:

docker exec -it sshlog sshlog attach 8 --readonly

Attached to TTY 8.  Press CTRL+Q to exit


Of course, you can stop/rm the container with:

docker stop sshlog && docker rm sshlog

try this export HISTTIMEFORMAT="%T " run a couple of commands and "history" afterwards...

You must log in to answer this question.

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