It seems that watch does the trick for FreeBSD, but for Linux there's only things like ttysnoop (for linux-2.6) but that requires you modify your /etc/inittab files which is a bore. There's also conspy but that only works with physical terminal devices not ptys, as far as the docs say...
However you can do it without altering anything:
- See what's being typed (and subsequent output) in another terminal session by using peekfd - you just need to supply the UID of the shell running on that other terminal (find it using ps). Watch out as the output may well contain some 8-bits chars which can confuse your current terminal - though you can get it back to normal using a terminal reset. (e.g. sudo peekfd /dev/pts/27)
- Inject characters into a terminal by using the TIOCSTI ioctl() with this neat Perl script (copied below). Find the tty of the process you're interested in (e.g. ps axg | grep vi) and use that as the argument to the perl script e.g. echo 'ZZ' | sudo ./catvt.pl /dev/pts/27
#!/usr/bin/perl -w
use strict;
use Fcntl;
use constant TIOCSTI => 0x5412;
unless (@ARGV >= 1) {
print "usage: $0 [vt] <input>\n";
exit; }
my $vt = shift @ARGV;
my $buf = join '', <>;
&writevt ($vt, $buf) || die "can't write to $vt: $!\n";
exit;
sub writevt {
my ($vt, $buf) = @_;
sysopen (VT, $vt, O_RDONLY) || return 0;
for (my $i = 0; $i < length $buf; $i++) {
ioctl (VT, TIOCSTI, substr ($buf, $i, 1)) || return 0; }
close (VT) || return 0;
return 1; }
[updated 6jan10]