如何拖尾远程文件?

时间:2009-02-19 16:30:27

标签: perl scripting ssh tail netcat

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

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

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

  3. 可以通过Perl调用。

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

  5. 我尝试的解决方案通常是这种

    ssh remotemachine -f <some command>
    

    “一些命令”一直是:

    tail -f logfile
    

    基本尾部不起作用,因为远程进程在本地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 $_;
    }
    

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

8 个答案:

答案 0 :(得分:56)

你试过吗

ssh -t remotemachine <some command>
来自ssh手册页的

-t选项:

 -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.

答案 1 :(得分:2)

一些想法:

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

答案 2 :(得分:2)

你可以尝试Survlog它的OS X.

答案 3 :(得分:1)

netcat应该为你做。

答案 4 :(得分:1)

您可以使用bash和rsync远程关闭文件。以下脚本取自本教程:Tail files remotely 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

答案 5 :(得分:0)

File::Tail。不知道它有帮助吗?

答案 6 :(得分:0)

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

答案 7 :(得分: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");