Как мне запрограммировать сценарий CGI для выполнения удаленного сценария через ssh и отображения данных из удаленного выполнения? - PullRequest
1 голос
/ 14 октября 2011

У меня есть конкретный случай, когда мне нужно разместить HTML-страницы и CGI-скрипты на ServerA, а CGI-скрипты должны будут вызывать Perl-скрипты на ServerB, которые будут извлекать данные из БД, а HTML-страницы на ServerA должны отображатьdata.

Я успешно удаленно запускаю скрипт perl, но не могу решить, как лучше всего вернуть данные с ServerB обратно на ServerA и отобразить их с этой архитектурой?

Я рассмотрел следующее: ServerB экспортирует данные в плоский файл, который передается обратно с помощью scp на ServerA.Scp может быть настроен в файле perl на сервере B.

Question1: Как мне заставить CGI на ServerA ждать, пока ServerB не вернет данные.Как мне обрабатывать случаи ошибок, когда данные не возвращаются или когда входные параметры, передаваемые на ServerB, неверны?

Вопрос2: Есть ли лучший способ программирования вокруг этого требования?

Ответы [ 4 ]

2 голосов
/ 14 октября 2011

Ваш скрипт должен инициировать другой процесс и выйти. Другой процесс должен оставить вывод в файле. Вам нужно будет настроить способ просмотра результатов, когда завершится другой процесс.

Для вдохновения, см. Рэндал Шварц Наблюдение за длинными процессами через CGI . В наши дни вы можете использовать CGI :: Session .

1 голос
/ 18 октября 2011

Лично у меня возникнет соблазн использовать DBD :: Proxy от ServerA с прокси-сервером на ServerB и получать данные "напрямую", что позволит вам манипулировать ими в сценарии CGI.Конечно, это предполагает, что данные, которые вам нужны, возвращаются достаточно быстро, чтобы ничего не затягивать.

1 голос
/ 18 октября 2011

Я предполагаю, что вы разветвляете удаленную команду SSH, поэтому возникает путаница с ожиданием завершения удаленной команды.Следующее делает то, что вы хотите:

open(my $F, "-|", "ssh $REMOTE_HOST $REMOTE_COMMAND") || die $!;

while(<$F>) {
  do_something_with_data($_);
}
1 голос
/ 14 октября 2011

Я не проверял это. Я взломал его из своего существующего кода, чтобы добавить комментарии.

Это должно работать, с небольшими изменениями.

Надеюсь, этого достаточно, чтобы вы начали.

use Net::SSH::Perl;
use Net::SCP qw(scp iscp);

$DEBUG = 0;

# Note: A public key exchange must first be created before this script will work
# without a password

$remHost = "machine.domain.sfx";
$remUser = "user_on_remote_machine";

# Name of file to send
$sndFile = "localfile.txt";

# scp is used to send the file to the remote host 
$scp = Net::SCP->new( $remHost, $remUser );
$scp->put( $sndFile ) or die $scp->{errstr};

$sndFile =~ s/.*\/(.*)/$1/;

# Use ssh to run a command remotely
$ssh = Net::SSH::Perl->new( $remHost );
eval{ $ssh->login( $remUser, "" ); }
    or $msg = "Cannot connect to $remHost - Net::SSH error: ".join( "", $@ );

# Copy the file to another directory on the remote host
$cmd = "cp $sndFile /opt/tmp";

if( $DEBUG > 0 )
    { print STDERR "cmd = $cmd\n"; }

# Execute the command
eval{ ($stdout, $stderr, $exit) = $ssh->cmd($cmd); };

if( $DEBUG > 0 )
{
    print STDERR "stderr = $stderr\n";
    if( $DEBUG > 1 )
        {   print STDERR "stdout = $stdout\n"; }
}

# Store the output of the ssh command in an array
@remArr = split( "\n", $stdout );
...