Perl SSH 指令中的特殊字元“#”

Perl SSH 指令中的特殊字元“#”

我嘗試在 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;

相關內容