我需要在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执行的反引号中插入变量名的正确方法是什么?它们可以连接吗?
答案 0 :(得分:22)
要将变量插入任何插值字符串(无论是qq//
还是qx
还是qr//
),只需执行"this is $foo!"
即可:变量名称(此处:{ {1}})由$foo
分隔,!
不能成为普通变量名称的一部分。
当Perl的命名规则中,部分字符串可能是名称的一部分时,这并不容易。例如:
my $genes = "ACTG$insert_genes_hereACTG";
Perl认为变量名称为$insert_genes_hereACTG
。
使用curlies来分隔名称:
my $genes = "ACTG${insert_genes_here}ACTG";
这始终有效并且是一种灵活的解决方案
连接字符串:
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;
顺便说一下,不使用反引号,并使用open
或system
代替(取决于您是否需要输出),可以避免许多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 );