我该怎么逃避! (bang / exclamation)在调用bash命令的perl脚本中?

时间:2015-03-30 18:15:41

标签: bash perl passwords escaping quotes

我正在更新旧版Perl脚本。它非常简单,因为它设置了一些变量,然后调用了一个bash命令。问题是我传递的密码中有2个惊叹号。这些似乎被翻译错了。说我有这个脚本:

$source_db_ip = "1.2.3.4"; # carl dev/qa
$source_user = 'user1';
$source_password = "password!!";

$destination_db_ip = "5.6.7.8";
$destination_user     = "user2";
$destination_password = "password2!!";

my $status = `pt-table-sync h=$source_db_ip,p='${source_password}',u=$source_user,D=db_name,t=table_name   h=$destination_db_ip,p='$destination_password',u='$destination_user',D=db_name,t=table_name`;

这一直在失败。我知道凭证是正确的,因为我手动检查了它们。那么我怎样才能正确地转义密码以便正确翻译?

1 个答案:

答案 0 :(得分:4)

通过使用`perl -E'say for \@ARGV' -- ...`可以看出,以下两个字符串作为参数传递:

h=1.2.3.4,p=password!!,u=user1,D=db_name,t=table_name
h=5.6.7.8,p=password2!!,u=user2,D=db_name,t=table_name

您没有指定预期的格式,但看起来是正确的。请注意,我会使用shell_quote而不是'$var'

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote(
   'pt-table-sync',
   join(',',
      "h=$source_db_ip",
      "p=$source_password",
      "u=$source_user",
      "D=db_name",
      "t=table_name",
   ),
   join(',',
      "h=$destination_db_ip",
      "p=$destination_password",
      "u=$destination_user",
      "D=db_name",
      "t=table_name",
   ),
);

`$cmd`