我尝试在 Perl 脚本中使用 SSH 使用 # 发送命令,但它在 # 处被截断
例子:
输入文本是:
$message = "Product ID # STK000134"
SSH 命令是:
$execute=`ssh -q id@host /usr/message/send -pin $pager_num -message $message`;
通过的是:
ssh -q id@host /usr/message/send -pin $pager_num -message Product ID
代替 :
ssh -q id@host /usr/message/send -pin $pager_num -message Product ID # STK000134
如何确保 # 和 # 后面的所有文本都能通过?
答案1
#
在 shell 中启动注释。添加引号:
$message =~ s/\#/\\\#/g;
$execute=`ssh -q id@host /usr/message/send -pin $pager_num -message "'$message'"`;
答案2
反引号调用 shell。 shell 将#
及其后的所有内容视为注释。
您需要正确引用插值,以便无论您的字符串碰巧包含什么字符(例如单引号、双引号、反引号、井号、美元符号、反斜杠等),shell 都不会“感到困惑”。
您可以使用这样的辅助子:
sub sq ($) {
# Bourne-style single quote $_[0]
# e.g.
# foo bar becomes 'foo bar'
# a'b becomes 'a'\''b'
# The following implementation does not yield the most compact
# representations, but it is dead simple.
my $sq = $_[0];
$sq =~ s/'/'\\''/g;
"'$sq'";
}
$execute=`ssh -q id@host /usr/message/send -pin @{[sq $pager_num]} -message @{[sq $message]}`;
如果您不关心命令字符串中间的所有噪音,那么您可以使用一些额外的变量:
my $sq_pager_num = sq $pager_num;
my $sq_message = sq $message;
$execute=`ssh -q id@host /usr/message/send -pin $sq_pager_num -message $sq_message`;
但这只能解决问题当地的壳。因为你正在使用SSH,一个外壳偏僻的系统也会解释你的字符串。所以,你实际上需要引用它们两次。
my $tsq_pager_num = sq sq $pager_num;
my $tsq_message = sq sq $message;
$execute=`ssh -q id@host /usr/message/send -pin $tsq_pager_num -message $tsq_message`;
作为使用本地 shell(并且必须引用它)的替代方法,您可以运行本地命令 (SSH) 直接使用 4+ 参数形式open
:
open CMD, '-|', qw(ssh -q id@host /usr/message/send -pin), sq $pager_num, '-message', sq $message;
{ local $/; $execute = <CMD>; }
close CMD;
答案3
使用网络::OpenSSH并让它为您进行引用:
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new('id@host');
my $output = $ssh->capture("/usr/message/send",
-pin => $pager_num,
-message => $message);
$ssh->error and die "ssh failed: " . $ssh->error;