17

我需要在 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 的正确方法是什么?它们可以串联吗?

4

3 回答 3

25

要将变量插入任何插值字符串(无论是它qq//还是qxqr//),只需执行"this is $foo!"以下操作就足够了:变量名称(此处: )由不能是正常变量名称的一部分的$foo分隔。!

如果按照 Perl 的命名规则,字符串的一部分可能是名称的一部分,这并不容易。例子:

my $genes = "ACTG$insert_genes_hereACTG";

Perl 认为变量名是$insert_genes_hereACTG. 这可以通过

  1. 使用花括号来分隔名称:

    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;
    

顺便说一句,许多外壳插值问题可以通过使用反引号而使用openorsystem来规避(取决于您是否需要输出)。

open

open my $command, "-|", "mogrify", "-resize", $wid . "x" . $hit, glob("*JPG")
  or die ...;

while (<$command>) { do something }

这完全绕过了 shell(而是exec直接绕过了 s),因此必须手动完成通配。对于system不止一个论点也是如此。

于 2013-06-09T12:32:59.933 回答
6

此问题并非特定于反引号。每当您在字符串中插入 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
于 2013-06-09T13:36:51.430 回答
5

除了其他好的响应外,还可以使用readpipe函数,相当于反引号和qx运算符。但与常规函数一样,您可以更好地控制其参数的插值方式。

$output = readpipe("mogrify -resize $wid" . "x$hit *.JPG");
$output = readpipe( sprintf "mogrify -resize %dx%d *.JPG", $wid, $hit );
于 2013-06-10T08:30:37.630 回答