我们有一个 Linux 服务器,可以运行诊断脚本 diag.pl
,它协调其他服务器的报告。
diag.pl
遍历子服务器,对于每个子服务器,SSH 进入并运行 bash 脚本,该脚本将信息传回:
my $cmd=sprintf("ssh %s sudo /usr/lib/support/report.sh -e %s | uudecode -o \"%s-outfile.tgz\") 2>%1 |", $server, $specialparam, $servername)
report.sh
中发送回数据的代码行是:
uuencode --base64 ${REPORT}.tar.gz /dev/stdout
我想更新 report.sh
以发回额外的一行信息,例如:
echo "special-file-found=${SFF}" > /tmp/sff.cfg
uuencode --base64 /tmp/sff.cfg > /dev/stdout
一旦找到特殊文件,Perl 脚本就会更新,不再将 specialparam
发送回后续的 report.sh
调用。
是否有发送该输入以便 Perl 轻松捕获它的好方法?
我尝试了什么
- 使用
setattr
在 tar.gz 上设置一个user.comment
属性,但是注释在 uuencoding 后无法保存 - 目前认为我最好的选择是使用上面的伪代码,创建一个新文件进行编码和发送,并更新 Perl 脚本以在每次新传输时检查它,直到找到特殊文件。
最佳答案
我认为目标是修改一个 shell 脚本,该脚本向调用者返回一个编码文件,以便它发送更多信息,特别是在调用者中用作标志的字符串。
尚不清楚如何从 Perl 脚本运行 shell 脚本,但有一些方法可以做到这一点,以便调用者返回打印的单独“行”,无论是在发出时还是在运行完成后全部.
然后您可以向 shell 脚本添加所需的额外打印到 STDOUT
,并在调用者中检查每一行 shell 输出以查看它是否符合某些“协议(protocol)”;例如,它是否是或以 special-file-found 字符串开头。然后您可以为进一步的调用设置标志或为后续运行编写控制文件等。否则,该行就是编码文件。
使用 pipe-open 编造的基本示例(见页尾)
use warnings;
use strict;
use feature 'say';
my @cmd = qw(ls -l ./);
my $file_found = quotemeta 'special-file-found';
my ($flag, $binfile);
my $pid = open(my $out, '-|', @cmd) // die "Can't open @cmd: $!";
while (<$out>) {
chomp;
if (/^$file_found/) {
$flag = 1;
}
else {
$binfile = $_;
# whatever else need be done, or perhaps last;
}
}
close $out;
此示例运行命令 ls -l ./
但您可以运行任何可执行文件来代替它,例如 @cmd = ('report.sh', 'arg1', 'arg2 ',...)
.
另一种方法是使用反引号 ( qx ) 并将其返回分配给一个数组,在这种情况下,每个元素都会收到一行输出。
还有一个更好的方法是使用管理外部命令的模块。例如,从简单到更强大:IPC::System::Simple , Capture::Tiny , IPC::Run3 , IPC::Run .
关于linux - 通过 SSH 通过 STDIN 将指示器从 Bash 传回 Perl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53764424/