views:

2478

answers:

7

I am trying to find a good way to tail a file on a remote host. This is on an internal network of Linux machines. The requirements are:

  1. Must be well behaved (no extra process laying around, or continuing output)

  2. Cannot require someone's pet Perl module.

  3. Can be invoked through Perl.

  4. If possible, doesn't require a custom built script or utility on the remote machine (regular linux utilities are fine)

The solutions I have tried are generally of this sort

ssh remotemachine -f <some command>

"some command" has been:

tail -f logfile

Basic tail doesn't work because the remote process continues to write output to the terminal after the local ssh process dies.

$socket = IO:Socket::INET->new(...);
$pid = fork();
if(!$pid)
{
  exec("ssh $host -f '<script which connects to socket and writes>'");
  exit;
}

$client = $socket->accept;
while(<$client>)
{
  print $_;
}

This works better because there is no output to the screen after the local process exits but the remote process doesn't figure out that its socket is down and it lives on indefinitely.

A: 

There is File::Tail. Don't know if it helps?

dsm
That doesn't do remote files by itself
Leon Timmermans
+2  A: 

Some ideas:

  • You could mount it over NFS or CIFS, and then use File::Tail.
  • You could use one of Perl's SSH modules (there are a number of them), combined with tail -f.
Leon Timmermans
A: 

rsync://[USER@]HOST[:PORT]/SRC... [DEST] | tail [DEST] ?

rupert0
The number and size of the log files makes rsync-ing them to the local machine impractical.
Frosty
rsync can be quite efficient as it only transfers the deltas. Additionally, since it can compress the data, and log files are usually quite compressible, it might work quite well. Yes, rsync does take a while if you have millions of files, but for thousands of large files it works quite well.
brianegge
+1  A: 

netcat should do it for you.

Ranjeet
I had a netcat based solution where forked and ran netcat on the remote machine and exec'ed a nc listener on the local machine which worked great but the ssh -t solution by Manni is even better.
Frosty
+14  A: 

Have you tried

ssh -t remotemachine <some command>

instead of

-f

?

innaM
Even better than what I found already. Thank you.
Frosty
simple and efficient, +1.
John T
A: 

Someone suggested using nc (netcat). This solution does work but is less ideal than just using ssh -t. The biggest problem is that you have to use nc on both sides of the connection and need to do some port discovery on the local machine to find a suitable port over which to connect. Here is the adaptation of the above code to use netcat:

$pid = fork();
if(!$pid)
{
  exec("ssh $host -f 'tail -f $filename |nc $localhost $port'");
  exit;
}

exec("nc -l -p $port");
Frosty
A: 

You could try Survlog Its OS X only though.

alt text

Kyle Browning