Как я могу скрыть удаленный файл?

Я пытаюсь найти хороший способ сохранить файл на удаленном хосте. Это во внутренней сети Linux-машин. Требования:

  1. Должен вести себя хорошо (никаких дополнительных процессов или продолжающегося вывода)

  2. Не может требоваться чей-то любимый Perl-модуль.

  3. Может вызываться через Perl.

  4. Если возможно, не требуется специально созданный скрипт или утилита на удаленной машине (подойдут обычные утилиты Linux)

Решения, которые я пробовал, обычно такого рода

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

Это работает лучше, потому что после выхода локального процесса нет вывода на экран, но удаленный процесс не понимает, что его сокет не работает, и живет бесконечно.


person Frosty    schedule 19.02.2009    source источник
comment
Приведенный вами пример кода не имеет абсолютно никакого смысла. Можете ли вы опубликовать настоящую вещь?   -  person Leon Timmermans    schedule 19.02.2009
comment
Что вы подразумеваете под удаленным процессом, продолжающим извергать? Когда одна из сторон ssh-соединения обрывается, другая тоже должна отключаться... озадачен   -  person Aaron Digulla    schedule 19.02.2009
comment
Да, я видел, как сеансы ssh умирали, и все, что через них работало, тоже хрипело, если только они не работали в сеансах отдельного экрана или что-то в этом роде.   -  person warren    schedule 19.02.2009
comment
@Aaron: из оболочки попробуйте: ssh host -f tail -f ‹somefile›, а затем нажмите Ctrl-C. На моей машине RedHat я продолжаю получать хвост файла в терминале, и удаленный SSH+хвост остается очень даже живым. Использование -t вместо -f исправляет это.   -  person Frosty    schedule 19.02.2009


Ответы (8)


Ты пытался

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.
person innaM    schedule 19.02.2009
comment
Столько побед! Я везде искал решение. -t такой элегантный и работает с такими вещами, как top! Спасибо :) - person Arthur Maltson; 25.09.2013
comment
Со страницы руководства ssh. -t Принудительное выделение псевдотерминала. Это можно использовать для выполнения произвольных экранных программ на удаленной машине. - person SomeGuyOnAComputer; 20.10.2015

Некоторые идеи:

  • Вы можете смонтировать его через NFS или CIFS, а затем использовать File::Tail.
  • Вы можете использовать один из модулей Perl SSH (их несколько) в сочетании с tail -f.
person Leon Timmermans    schedule 19.02.2009

Вы можете попробовать Survlog только для OS X.

person Kyle Browning    schedule 20.02.2010
comment
Я только что попробовал, и, похоже, это вообще не сработало; не поддерживается с 2015 года. Пустая трата 3 долларов. - person stephan.com; 03.10.2019
comment
Привет @stephan.com. Я сделал приложение survlog. Скоро выйдет обновление, которое больше не будет стоить вам денег. - person Kyle Browning; 09.10.2019

netcat должен сделать это за вас.

person Ranjeet    schedule 19.02.2009
comment
У меня было решение на основе netcat, в котором разветвлялся и запускался netcat на удаленной машине, а на локальной машине выполнялся прослушиватель nc, который отлично работал, но решение ssh -t от Manni даже лучше. - person Frosty; 19.02.2009

Вы можете удаленно загружать файлы с помощью bash и rsync. Следующий сценарий взят из этого руководства: Tail-файлы удаленно с помощью 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
person user1381775    schedule 08.05.2012
comment
Ребята, мой товарищ по команде — король bash, и мы решили эту проблему с помощью скрипта bash и rsync. он работает в prod как мечта. - person user1381775; 08.05.2012

rsync://[USER@]HOST[:PORT]/SRC... [DEST] | хвост [DEST] ?

person rupert0    schedule 19.02.2009
comment
Количество и размер файлов журналов делают непрактичной их rsync-синхронизацию с локальным компьютером. - person Frosty; 19.02.2009
comment
rsync может быть весьма эффективным, поскольку он передает только дельты. Кроме того, поскольку он может сжимать данные, а файлы журналов обычно достаточно сжимаемы, он может работать достаточно хорошо. Да, rsync требует времени, если у вас есть миллионы файлов, но для тысяч больших файлов он работает достаточно хорошо. - person brianegge; 09.06.2009

Кто-то предложил использовать 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");
person Frosty    schedule 19.02.2009

Существует File::Tail. Не знаю, поможет ли?

person dsm    schedule 19.02.2009
comment
Это не делает удаленные файлы само по себе - person Leon Timmermans; 19.02.2009