2012-08-08 72 views
1

我正在使用Net :: OpenSSH使用Web前端执行远程命令。我的命令在命令行上没有失败地返回,但是在Web浏览器中我什么也得不到。我已经做了几个小时的研究无济于事 - 有什么想法?在浏览器中显示输出Perl CGI SSH

下面是一些代码给你一个例子(一些显而易见的原因被删除)。

#!/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 

干杯!

+1

'$ ssh-error and die'?样本中的拼写错误还是更糟? :) – 2012-08-08 16:10:50

+0

另外,服务器错误日志说什么? – 2012-08-08 16:11:53

+0

什么是服务器和操作系统? – 2012-08-08 16:12:38

回答

1

我维护CGI.pm.我建议您将这些添加到您的简单脚本中:

  1. 在打印其他内容之前,请打印标准HTTP标头:print header();
  2. use CGI行后面加上这个:use CGI::Carp qw(fatalsToBrowser); ......这将在浏览器中显示任何运行时问题。如果在这些更改之后没有得到任何输出,请检查脚本是否编译为perl -cw script.pl
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; 
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二进制文件,会继承这些流。