如何远程跟踪文件?

49

我正在尝试找到一种好的方式来追踪远程主机上的文件。这是在Linux机器的内部网络中进行的。要求如下:

  1. 必须表现良好(没有额外的进程残留或继续输出)

  2. 不能依赖于某个人的Perl模块。

  3. 可以通过Perl调用。

  4. 如果可能的话,不需要在远程机器上构建自定义脚本或实用程序(常规Linux实用程序就可以)。

我尝试过的解决方案通常是这种类型的:

ssh remotemachine -f <some command>
"

some command

已经完成:"
tail -f logfile

基本的tail命令无法工作,因为远程进程在本地ssh进程结束后继续向终端输出。

$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 $_;
}

这种方法更好,因为本地进程退出后不会在屏幕上输出任何内容,但远程进程并没有意识到它的套接字已经关闭,因此它会无限期地继续运行。


你发布的代码示例根本没有任何意义。你能发真正的代码吗? - Leon Timmermans
“远程进程继续喷出”是什么意思?当ssh连接的任一一端死亡时,另一端也应该跟着死亡... 困惑 - Aaron Digulla
是的 - 我见过ssh会话死掉,无论其中运行的内容如何,除非它们在分离的屏幕会话中运行或其他类似的东西。 - warren
@Aaron:从 shell 尝试:ssh host -f "tail -f <somefile>",然后按 Ctrl-C。在我的 RedHat 机器上,我继续在终端中获取文件的尾部,并且远程 SSH+tail 仍然非常活跃。使用 -t 而不是 -f 可以解决这个问题。 - Frosty
8个回答

81

你试过了吗?

ssh -t remotemachine <some command>

-t option from the ssh man page:

 -t      Force pseudo-tty allocation. This can be used to execute 
         arbitrary screen-based programs on a remote machine, which
         can be very useful, e.g. when implementing menu services.
         Multiple -t options force tty allocation, even if ssh has no local tty.

替代

 -f      Requests ssh to go to background just before command execution.  
         This is useful if ssh is going to ask for passwords or passphrases, 
         but the user wants it in the background.
         This implies -n.  The recommended way to start X11 programs at a remote
         site is with something like ssh -f host xterm.

太棒了!我一直在到处寻找解决方案。-t非常优雅,而且还可以与top等东西一起使用!谢谢 :) - Arthur Maltson
从ssh手册中。"-t 强制伪终端分配。这可用于在远程机器上执行任意基于屏幕的程序" - SomeGuyOnAComputer

2
您可以尝试使用Survlog,但它只能在OS X上运行。

我刚试了一下,似乎完全没用;自2015年以来就没有维护了。三美元的浪费。 - stephan.com
嗨 @stephan.com。我制作了名为survlog的应用程序。很快将推出更新,不会再收取您任何费用。 - Kyle Browning

2

一些想法:

  • 你可以挂载NFS或CIFS,然后使用File::Tail
  • 你可以使用Perl的SSH模块之一(有很多),结合tail -f

1

您可以使用bash和rsync远程跟踪文件。以下脚本摘自此教程:使用bash和rsync远程跟踪文件

#!/bin/bash
#Code Snippet from and copyright by sshadmincontrol.com
#You may use this code freely as long as you keep this notice.

PIDHOME=/a_place/to/store/flag/file
FILE=`echo ${0} | sed 's:.*/::'`
RUNFILEFLAG=${PIDHOME}/${FILE}.running

if [ -e $RUNFILEFLAG ]; then
   echo "Already running ${RUNFILEFLAG}"
   exit 1
else
   touch ${RUNFILEFLAG}
fi

hostname=$1 #host name to remotlely access
log_dir=$2  #log directory on the remotehost
log_file=$3 #remote log file name
username=$3 #username to use to access remote host
log_base=$4 #where to save the log locally

ORIGLOG="$log_base/$hostname/${log_file}.orig"
INTERLOG="$log_base/$hostname/${log_file}.inter"
FINALLOG="$log_base/$hostname/${log_file}.log"

rsync -q -e ssh $username@$hostname:$log_dir/$log_file ${ORIGLOG}
grep -Ev ".ico|.jpg|.gif|.png|.css" > ${INTERLOG}  

if [ ! -e $FINALLOG ]; then
   cp  ${INTERLOG} ${FINALLOG}
else
   LINE=`tail -1 ${FINALLOG}`
   grep -F "$LINE" -A 999999999 ${INTERLOG} \
      | grep -Fv "$LINE" >> ${FINALLOG}
fi

rm ${RUNFILEFLAG}
exit 0

伙计们,我的队友是Bash之王,我们用Bash脚本和rsync解决了那个问题。现在它在生产环境中像梦幻一样运行良好。 - user1381775

1

netcat 可以为您完成此操作。


我曾经有一个基于netcat的解决方案,在远程机器上fork并运行了netcat,并在本地机器上执行了nc监听器,这个方案非常好,但是Manni提供的ssh -t解决方案更好。 - Frosty

0

有人建议使用nc(netcat)。这个解决方案确实可行,但不如只使用ssh -t理想。最大的问题是你必须在连接的两端都使用nc,并且需要在本地机器上进行一些端口发现,以找到一个合适的端口来连接。以下是将上述代码改为使用netcat的方法:

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

exec("nc -l -p $port");

0

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

的意思是什么?


日志文件的数量和大小使得将它们同步到本地机器变得不切实际。 - Frosty
rsync 可以非常高效,因为它只传输增量。此外,由于它可以压缩数据,并且日志文件通常是可压缩的,所以它可能会表现得非常好。是的,如果您有数百万个文件,rsync 需要一些时间,但对于数千个大文件,它表现得非常好。 - brianegge

-1

它本身不支持远程文件。 - Leon Timmermans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接