46

我正在尝试找到一种在远程主机上跟踪文件的好方法。这是在 Linux 机器的内部网络上。要求是:

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

  2. 不能要求某人的宠物 Perl 模块。

  3. 可以通过 Perl 调用。

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

我尝试过的解决方案一般都是这种

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

这效果更好,因为在本地进程退出后没有输出到屏幕,但远程进程没有发现它的套接字已关闭并且它无限期地存在。

4

8 回答 8

75

你有没有尝试过

ssh -t remotemachine <some command>

-t 来自 ssh 手册页的选项:

 -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.
于 2009-02-19T17:05:16.103 回答
2

一些想法:

  • 您可以通过 NFS 或 CIFS 安装它,然后使用File::Tail
  • 您可以使用 Perl 的 SSH 模块之一(有很多),结合tail -f.
于 2009-02-19T16:38:33.683 回答
2

不过,您只能尝试Survlog它的 OS X。

于 2010-02-20T22:44:20.597 回答
1

netcat 应该为你做这件事。

于 2009-02-19T17:01:37.687 回答
1

您可以使用 bash 和 rsync 远程跟踪文件。以下脚本取自本教程:Tail files remote using bash and 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
于 2012-05-08T10:16:30.683 回答
0

rsync://[USER@]HOST[:PORT]/SRC... [DEST] | 尾巴 [目的地] ?

于 2009-02-19T16:57:34.900 回答
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");
于 2009-02-19T17:30:03.607 回答
-1

File::Tail。不知道有没有帮助?

于 2009-02-19T16:33:48.730 回答