在浏览器Perl CGI SSH中显示输出

时间:2012-08-08 15:20:17

标签: perl ssh cgi openssh

我正在使用网络前端使用Net :: OpenSSH执行远程命令。我的命令在命令行中没有失​​败地返回,但我在Web浏览器中什么也得不到。我做了几个小时的研究没有用 - 任何想法?

这里有一些代码可以给你一个例子(由于显而易见的原因,有些代码被移除)。

#!/usr/bin/perl -w
use strict;
use CGI ':standard';
use Net::OpenSSH;
# Here in the code is just the header and standard tags
print "1";
print "2"; # both display
my $ssh = Net::OpenSSH->new($host, user => $uname, key_path => $key); # all works
$ssh- error and die "Can't ssh to host" . $ssh->error;
print "3";
$ssh->system("uname -a") or
die "remote command failed: " . $ssh->error;
my @lsa = $ssh->capture("ls -a");
$ssh->error and
die "remote ls command failed: ". $ssh->error;

print "4";
print "5"; 
print @lsa; # won't display in browser, just terminal/CLI

干杯!

3 个答案:

答案 0 :(得分:1)

我维持CGI.pm.我建议您在简单的脚本中添加这些内容:

  1. 在打印其他内容之前,请打印标准HTTP标头:print header();
  2. use CGI行之后添加此行:use CGI::Carp qw(fatalsToBrowser); ...将在浏览器中显示任何运行时问题。如果在这些更改后没有获得任何输出,请检查脚本是否使用perl -cw script.pl
  3. 进行编译

答案 1 :(得分:0)

下面是关于在Debian机器上为我工作的最小Perl代码。我建议你仔细检查并将其与实际代码进行比较。

然而,它在我的Debian上没有开箱即用,我做了一些决定,其中大多数可能不是很安全,但更多的是关于特定的环境:

  • 让服务器运行可写的用户回家(/ var / www)
  • 预先将主机添加到〜/ .ssh / known_hosts
  • 使用strict_mode => 0绕过Net::OpenSSH的安全检查,而不是找到正确的  ctl_dirNet::OpenSSH要求文件夹和所有上述文件夹严格为0755或更高,  所以/ tmp我用的通常不够好)

我相信有比这更安全的做法,但正如我所说,这是针对环境的。

所以代码:

#!/usr/bin/perl
use strict;
use warnings;

use Net::OpenSSH;
use File::Temp qw/ tempdir /;

# necessary minimum for CGI
print "Content-type: text/plain\n\n";

# prepare temp dir
my $temp = tempdir("/tmp/sshme.pl-XXXXXXXX", CLEANUP => 1);

# open SSH session
my %opts = (
    user        => "user",
    password    => "password",
    ctl_dir     => $temp,
    strict_mode => 0            ## NOT recommended - see my comments
);
my $ssh = Net::OpenSSH->new("host", %opts);
$ssh->error
    and die "Couldn't establish SSH connection: ". $ssh->error;

# perform command and print output
my @lines = $ssh->capture("ls")
    or die "remote command failed: " . $ssh->error;
print @lines;

答案 2 :(得分:0)

也许您的错误会转向标准错误,而不是标准输出。在这种情况下,它们通常最终会出现在服务器日志中,而不是浏览器窗口中。也许您可以使用POSIX::dup2来避免这种情况:

use POSIX;

# Make sure to send HTTP headers before redirecting streams!

POSIX::close(2);  # close original stderr stream. No more output to apache logs!!!
POSIX::dup2(1,2); # redirect error stream to standard output, so errors will appear in browser.

由perl发起的进程,例如一些ssh二进制文件将继承这些流。