#
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'"';
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?
#
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'"';
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;
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;
Tags ssh perl shell command-substitution