我正在使用Web前端使用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
干杯!
我维护 CGI.pm。我建议在您的简单脚本中添加以下内容:
- 在打印其他任何内容之前,请打印标准 HTTP 标头:
print header()
; - 在
use CGI
行后添加以下内容:use CGI::Carp qw(fatalsToBrowser);
...这将在浏览器中显示任何运行时问题。如果在这些更改后未获得任何输出,请检查脚本是否使用perl -cw script.pl
编译
下面是关于在 Debian 机器上为我工作的最低 Perl 代码。 我建议您浏览一下并将其与您的实际代码进行比较。
然而,它在我的 Debian 上并没有开箱即用,我做了一些决定,其中大多数可能不是很安全,但这更多的是关于特定的环境:
- 为服务器运行可写的用户提供主页 (/var/www)
- 事先将主机添加到 ~/.ssh/known_hosts
- 使用
strict_mode => 0
绕过Net::OpenSSH
的安全检查,而不是找到合适的ctl_dir
(Net::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/plainnn";
# 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;
也许您的错误被定向到标准错误,而不是标准输出。在这种情况下,它们通常会出现在服务器日志中,而不是浏览器窗口中。也许您可以使用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 二进制文件,将继承这些流。