如何在反引号中正确使用perl变量名?

时间:2013-06-09 12:12:09

标签: perl variables backticks

我需要在bash shell上执行以下代码:

mogrify -resize 800x600 *JPG

由于宽度和高度是变量,我试过这个:

`mogrify -resize $widx$hit *JPG`

然而,在编译中,我得到Global symbol "$widx" requires explicit package name at getattach.pl line 131.的错误,这是因为编译器将$ widx视为一个新的未声明的变量,而不是$ wid和x。

我尝试在反引号中插入双引号,但代码的执行在没有任何消息的情况下停止。

在shell执行的反引号中插入变量名的正确方法是什么?它们可以连接吗?

3 个答案:

答案 0 :(得分:22)

要将变量插入任何插值字符串(无论是qq//还是qx还是qr//),只需执行"this is $foo!"即可:变量名称(此处:{ {1}})由$foo分隔,!不能成为普通变量名称的一部分。

当Perl的命名规则中,部分字符串可能是名称的一部分时,这并不容易。例如:

my $genes = "ACTG$insert_genes_hereACTG";

Perl认为变量名称为$insert_genes_hereACTG

可以解决这个问题
  1. 使用curlies来分隔名称:

    my $genes = "ACTG${insert_genes_here}ACTG";
    

    这始终有效并且是一种灵活的解决方案

  2. 连接字符串:

    my $genes = "ACTG" . $insert_genes_here . "ACTG";
    

    对于非qq引号,这有点困难。解决方案是创建一个临时变量来保存整个字符串,然后将其插入到特殊引号中:

    my $command = "mogrify -resize " . $wid . "x" . $hit. " *JPG";
    `$command`;
    

    此变体是使用sprintf插值:

    my $command = sprintf 'mogrify -resize %dx%d *JPG', $wid, $hit;
    
  3. 顺便说一下,使用反引号,并使用opensystem代替(取决于您是否需要输出),可以避免许多shell插值问题

    使用open

    open my $command, "-|", "mogrify", "-resize", $wid . "x" . $hit, glob("*JPG")
      or die ...;
    
    while (<$command>) { do something }
    

    这完全绕过shell(而不是直接exec),因此必须手动完成globbing。具有多个参数的system也是如此。

答案 1 :(得分:5)

此问题并非特定于反引号。只要在字符串中插入Perl变量,就会出现问题。

my $wid = 800;
my $hit = 600;

print "$widx$hit"; # this has the same problem

问题是Perl编译器无法知道变量名称(“wid”)的结束位置以及字符串(“x”)的固定位是否开始。所以它假设它正在寻找一个名为$widx的变量 - 它不存在。

解决方案是将变量的名称放在{ ... }

my $wid = 800;
my $hit = 600;

print "${wid}x$hit"; # This works

答案 2 :(得分:2)

除了其他好的回复之外,您还可以使用readpipe功能,该功能相当于反引号和qx运算符。但是,就像常规函数一样,您可以更好地控制对其参数的插值方式。

$output = readpipe("mogrify -resize $wid" . "x$hit *.JPG");
$output = readpipe( sprintf "mogrify -resize %dx%d *.JPG", $wid, $hit );