Caractere especial '#' no comando Perl SSH

7

Eu tento enviar o comando usando SSH no meu script perl com #, mas ele fica truncado em #

Exemplo:

O texto de entrada é:

$message = "Product ID # STK000134"

O comando SSH é:

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

Qual é a passagem:

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

Em vez de:

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

Como posso garantir que # e todo o texto por trás do # seja obtido?

    
por user37500 19.04.2013 / 11:55

3 respostas

10

# inicia um comentário no shell. Adicione citações:

$message =~ s/\#/\\#/g;
$execute='ssh -q id@host /usr/message/send -pin $pager_num -message "'$message'"';
    
por 19.04.2013 / 12:00
2

Os backticks chamam um shell. O shell trata o # e tudo depois dele como comentário.

Você precisa citar corretamente os valores interpolados para que o shell não fique "confuso", não importando quais caracteres suas strings contenham (por exemplo, aspas simples, aspas duplas, backticks, sinais de libra, cifrões, barras invertidas, etc. ).

Você pode usar um auxiliar como este:

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

Se você não se importa com todo o barulho no meio da sua string de comando, então você pode usar algumas variáveis extras:

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

Mas isso só resolve o problema do shell local . Como você está usando ssh , um shell no sistema remoto também interpretará suas strings. Então, você precisa citá-los duas vezes .

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

Como uma alternativa ao uso de um shell local (e ter que citá-lo), você pode executar o comando local ( ssh ) diretamente usando o formulário de argumento 4+ de open :

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

use Net :: OpenSSH e deixe-o fazer as citações para você:

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;
    
por 18.06.2015 / 22:27