Sonderzeichen '#' im Perl-SSH-Befehl

7

Ich versuche, einen Befehl mit SSH in meinem Perl-Skript mit # zu senden, aber er wird direkt bei # abgeschnitten

Beispiel:

Der eingegebene Text lautet:

$message = "Product ID # STK000134"

Der SSH-Befehl lautet:

$execute=`ssh -q id@host /usr/message/send -pin $pager_num -message $message`;

Was passiert ist:

ssh -q id@host /usr/message/send -pin $pager_num -message Product ID 

Anstatt von :

ssh -q id@host /usr/message/send -pin $pager_num -message Product ID # STK000134

Wie stelle ich sicher, dass # und der gesamte Text hinter # durchkommen?

user37500
quelle

Antworten:

10

#Startet einen Kommentar in der Shell. Zitate hinzufügen:

$message =~ s/\#/\\\#/g;
$execute=`ssh -q id@host /usr/message/send -pin $pager_num -message "'$message'"`;
Choroba
quelle
2

Die Backticks rufen eine Shell auf. Die Shell behandelt das #und alles danach als Kommentar.

Sie müssen die interpolierten Werte richtig in Anführungszeichen setzen, damit die Shell nicht „verwirrt“ wird, unabhängig davon, welche Zeichen Ihre Zeichenfolgen enthalten (z. B. einfache Anführungszeichen, doppelte Anführungszeichen, Backticks, Pfundzeichen, Dollarzeichen, Backslashes usw.).

Sie können ein Hilfsprogramm wie das folgende verwenden:

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]}`;

Wenn Sie sich nicht um das gesamte Rauschen in der Mitte Ihrer Befehlszeichenfolge kümmern, können Sie einige zusätzliche Variablen verwenden:

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`;

Dies löst jedoch nur das Problem für die lokale Shell. Da Sie ssh verwenden , interpretiert eine Shell auf dem Remote- System auch Ihre Zeichenfolgen. Sie müssen sie also tatsächlich zweimal zitieren .

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`;

Alternativ zur Verwendung einer lokalen Shell (und zum Zitieren dafür) können Sie den lokalen Befehl ( ssh ) direkt ausführen, indem Sie die 4+ -Argumentform verwenden open:

open CMD, '-|', qw(ssh -q id@host /usr/message/send -pin), sq $pager_num, '-message', sq $message;
{ local $/; $execute = <CMD>; }
close CMD;
Chris Johnsen
quelle
2

Verwenden Sie Net :: OpenSSH und lassen Sie es das Zitat für Sie erledigen:

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;
Salve
quelle