【问题标题】:Include a perl variable inside a bash command in a perl script在 perl 脚本的 bash 命令中包含 perl 变量
【发布时间】:2017-08-11 07:42:46
【问题描述】:

例如:

#!/usr/bin/perl
...
my $host = $db_conf->{host};
my @cmd = ('date',$host);
system(@cmd);

所以我期待的结果是:

Fri Aug 11 15:41:28 CST 2017 db-test-1

以 db-test-1 为主机名。

这是我的全部代码:

#!/usr/bin/perl

use strict;
use warnings;

use 5.010;
use DBI;
use Encode;
use IO::File;
use JSON;
use utf8;

BEGIN {
    binmode STDERR, ':utf8';
    binmode STDIN, ':utf8';
    binmode STDOUT, ':utf8';
}

INIT {
    my @databases = </kkcorp/kksecret/db-*/db.json>;

    foreach my $filename (@databases) {
        my $fh = IO::File->new($filename, 'r') or croak $!;
        my @buf = <$fh>;
        my $str = join '', @buf;
        $fh->close;

        my $db_conf = decode_json $str;

        my $entry = int(rand(scalar(@{$db_conf})));
        $db_conf = $db_conf->[$entry]->{writer}->{params};

        my $host = $db_conf->{host};
        my $dbname = $db_conf->{dbname};
        my $password = $db_conf->{password};
        my $username = $db_conf->{username};

        my $wsrep_check = `mysql -h $host -u $username -p$password < /authdir/auto_inc_script.sql`;
$hosti
        if (index($wsrep_check, 'Value: Synced') != -1) {
            my @cmd = ('date ${host}');
            system(@cmd);
            my @wsrep_check_lines = split /\n/, $wsrep_check;
            my @table_name = grep { /Synced/ } @wsrep_check_lines;
            for my $line (@table_name){
                say STDERR $line;
            }
            say '';
        }
   }
}

__END__

所以我想在“if”语句开始之后的两个语句中实现什么。代码运行良好,但忽略了 ${host} 变量,没有显示任何输出。

以下是我的结果:

Fri Aug 11 17:13:19 CST 2017
ok        Value: Synced

Fri Aug 11 17:13:20 CST 2017
ok        Value: Synced

【问题讨论】:

  • 开启use strict;use warnings;。检查错误的内容。发布一些输出。发布更多细节,因为我们不知道 db_conf 是什么。但我很确定你的system 命令是错误的,因为date localhost 错误与invalid date
  • 我已经添加了完整的代码,并详细解释了我想要实现的目标。
  • 您的 my @cmd = ('date ${host}'); 有单引号,因此 ${host} 不会被插值。后面的system 运行date ${host}。这不是你想要的,对吧?除此之外,我从mysql .. 中的描述中不明白问题出在哪里?
  • 当我使用双引号而不是单引号时,我收到错误“日期:无效日期...”
  • 但是date ${host} 的意义何在? ${host} 是什么?它是否应该被插值,因为$host 来自数据库?如果是,那么最好使用date 命令所期望的日期格式。但是按照你的方式,你运行date,后跟一个(假定的)变量${host},它应该存在于你的环境中......真的吗?

标签: bash shell perl


【解决方案1】:

system 非常强大但也非常危险。很容易造成灾难,考虑一下,如果你用rm 喂它,最好在运行system 之前绝对清楚rm 得到什么参数。

出于这个原因,我一直遵循这种做法:

  1. 创建逗号字符串
  2. 打印命令字符串
  3. 检查打印表示是否是我想要发送到 shell 的内容
  4. 添加system部分

这是一个示例,来自命令行:

perl -e ' $var = "Hello"; $cmd = qq(echo $var); print "The command: $cmd \n";'

接下来,添加系统:

perl -e ' $var = "Hello"; $cmd = qq(echo $var); print "the command: $cmd \n"; system($cmd);'

【讨论】:

  • 我了解 system() 的危险。无论如何,当我运行 echo $(date) 时,它会显示日期。但是,当我运行您建议的命令用 $(date) 替换字符串“hello”时,它不会打印日期。例如 perl -e ' $var = "$(date); $cmd = qq(echo $var); print \"命令:$cmd \n\";'
  • 试试这个:perl -e '$date = qx(date); chomp $date; $cmd=qq(echo "$date" ); print "cmd is : $cmd \n"; system($cmd);'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2012-10-17
  • 2017-06-15
  • 2014-03-24
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多