4

BSD systems have a neat watch tool for snooping other ttys :

Have you ever had a user login to your box and then ask you for help? Or have you ever been curious as to what your users are doing on your system? The watch(8) utility will let you snoop another tty, allowing you to see what your other users are doing and even interact with them. It’s a must-have utility for every network administrator.

Unfortunately watch is a different beast on linux.

So far I've got:

  • ttysnoop requires modifying /etc/inittab which is a pain
  • conspy couldn't get it to work so far
  • peekfd works but only one way (you can see user input but not output)
  • screen is nice of course but user needs to use screen ...

Isn't there a good equivalent for linux ?

  • I'm sure someone must have written a systemtap script for this ... – lemonsqueeze May 6 '16 at 13:16
  • Ah, here it is. – lemonsqueeze May 6 '16 at 17:30
1

You can specify multiple file descriptors for peekfd.

e.g.

peekfd -n -8 -d -c 24184 0 1 2

will snoop on stdin, stdout, and stderr of pid 24184.

The -c option will also attach to any child processes. This is necessary in order to see the ouput from them (e.g. seeing the output of ls that has been run in a snooped-on shell process)

Strangely, I find that it always successfully attaches to the child (no matter what child process I run in the snooped-on tty - ls, uname, /bin/echo as opposed to the built-in echo) but also always prints an error message Error attaching to pid -38 (and the "pid" is always -38).

man peekfd says:

DIAGNOSTICS

The following diagnostics may be issued on stderr:

  Error attaching to pid ...

An unknown error occurred while attempted to attach to a process.. you may need to be root.

Looks like a bug to me - I am running peekfd as root, and it always prints the error message, always with that same bogus (-38) PID.

BEWARE: the man page also says:

BUGS

Probably lots. Don't be surprised if the process you are monitoring dies.

  • Neat, terminal output is almost perfect. peekfd seems to interfere with the shell though, ^C at the prompt does nothing while it's running for example. – lemonsqueeze May 6 '16 at 5:27
  • you must be trapping ^C or something because ^C kills peekfd for me. – cas May 6 '16 at 5:28
  • Sorry, I meant ^C in the shell's window – lemonsqueeze May 6 '16 at 5:46
  • ah, right. i see what you mean. yes, that is broken. – cas May 6 '16 at 5:50
  • Also it doesn't work for pipes (dumps output from all processes !) – lemonsqueeze May 6 '16 at 13:09
1

SystemTap

3 lines, problem solved, SystemTap completely rules:

Install SystemTap, create ptysnoop file:

#!/usr/bin/stap

probe kernel.function("pty_write") {
    if (kernel_string($tty->name) == @1) {
            printf("%s", kernel_string_n($buf, $c))
    }
}

Make it executable. Now to watch /dev/pts/6 you just:

$ sudo ptysnoop pts6

Edit: other solutions found earlier

ttyrpld looks pretty solid:

ttyrpld is a multi-os kernel-level tty logger (key and screenlogger for ttys) with (a)synchronous replay support. It supports most tty types, including vc, bsd and unix98-style ptys (xterm/ssh), serial, isdn, etc. Being implemented within the kernel makes it unavoidable for the default user. It runs with no overhead if the logging daemon is not active.

You need a kernel module for it though.


I ended started up writing a small strace-based ttylogger tool which works well for my needs. All you need is perl and strace:

$ sudo ttylogger pid

Use this with user shell's pid to dump output from all subsequent commands.
See readme for details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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