如何编写CGI脚本以通过ssh执行远程脚本并显示远程执行中的数据?

时间:2011-10-14 14:39:48

标签: perl apache ssh cgi ssh-keys

我有这种特殊情况,我必须在ServerA上放置HTML页面和CGI脚本,CGI脚本必须调用ServerB上的Perl脚本,它将从数据库中获取数据,而ServerA上的HTML页面将显示数据

我成功地远程触发了perl脚本,但我无法确定将ServerB中的数据恢复到ServerA的最佳方法是什么,并将其显示在此架构中?

我考虑过以下事项: ServerB将数据导出到flatfile,该文件使用scp传回ServerA。可以在serverB上的perl文件中配置scp。

问题1:如何让ServerA上的CGI等到ServerB返回数据。如何处理未返回数据或传递给ServerB的输入参数不正确的错误情况?

问题2:有没有更好的方法来围绕这个要求进行编程?

4 个答案:

答案 0 :(得分:2)

您的脚本应启动其他进程并退出。另一个进程应该将输出保留在文件中。您需要为用户设置一种方法,以便在其他流程结束时查看结果。

有关灵感,请参阅Randal Schwartz的Watching long processes through CGI。现在,您可以使用CGI::Session

答案 1 :(得分:1)

我没有测试过这个。我用一些现有的代码来修改它以添加注释。

工作,只需稍加修改。

我希望这足以让你开始。

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 );

答案 2 :(得分:1)

我假设您正在分配远程SSH命令,因此混淆了等待远程命令完成。以下是您想要的:

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

while(<$F>) {
  do_something_with_data($_);
}

答案 3 :(得分:1)

就个人而言,我很想使用ServerA上的DBD::Proxy和ServerB上的代理,并“直接”获取数据 - 允许您在CGI脚本中操作它。当然,这假设您需要的数据足够快地返回,不会计算任何时间。