Joe*_*hew 15 variables perl backticks
我需要在bash shell上执行以下代码:
mogrify -resize 800x600 *JPG
Run Code Online (Sandbox Code Playgroud)
由于宽度和高度是变量,我试过这个:
`mogrify -resize $widx$hit *JPG`
Run Code Online (Sandbox Code Playgroud)
但是在编译时,我得到了错误Global symbol "$widx" requires explicit package name at getattach.pl line 131.,这是因为编译器将$ widx视为新的未声明变量而不是$ wid和x.
我尝试在反引号中插入双引号,但代码的执行在没有任何消息的情况下停止.
在反引号中为shell执行插入变量名的正确方法是什么?它们可以连接吗?
amo*_*mon 23
要将变量插入到任何插值字符串(be qq//或qxor qr//)中,只需执行即可"this is $foo!":变量名称(此处$foo:)由!不能是普通变量名称的一部分分隔.
如果字符串的某些部分可以通过Perl的命名规则成为名称的一部分,那就不那么容易了.例:
my $genes = "ACTG$insert_genes_hereACTG";
Run Code Online (Sandbox Code Playgroud)
Perl认为变量名称是$insert_genes_hereACTG.这可以通过以下方式解决
使用curlies来分隔名称:
my $genes = "ACTG${insert_genes_here}ACTG";
Run Code Online (Sandbox Code Playgroud)
这始终有效并且是一种灵活的解决方案
连接字符串:
my $genes = "ACTG" . $insert_genes_here . "ACTG";
Run Code Online (Sandbox Code Playgroud)
对于非qq引号,这有点困难.解决方案是创建一个临时变量来保存整个字符串,然后将其插入到特殊引号中:
my $command = "mogrify -resize " . $wid . "x" . $hit. " *JPG";
`$command`;
Run Code Online (Sandbox Code Playgroud)
其中一个变体是使用sprintf插值:
my $command = sprintf 'mogrify -resize %dx%d *JPG', $wid, $hit;
Run Code Online (Sandbox Code Playgroud)顺便说一句,许多shell插值问题可以通过不使用反引号,使用open或system代替(取决于你是否需要输出)来规避.
用open:
open my $command, "-|", "mogrify", "-resize", $wid . "x" . $hit, glob("*JPG")
or die ...;
while (<$command>) { do something }
Run Code Online (Sandbox Code Playgroud)
这完全绕过了shell(而不是exec直接),因此必须手动完成globbing.对于system不止一个论点也是如此.
此问题并非特定于反引号.每当您在字符串中插入Perl变量时,就会发生此问题.
my $wid = 800;
my $hit = 600;
print "$widx$hit"; # this has the same problem
Run Code Online (Sandbox Code Playgroud)
问题是Perl编译器无法知道变量名称("wid")的结束位置以及字符串("x")的固定位是否开始.所以它假设它正在寻找一个名为$widx- 不存在的变量.
解决方案是将变量的名称放入{ ... }.
my $wid = 800;
my $hit = 600;
print "${wid}x$hit"; # This works
Run Code Online (Sandbox Code Playgroud)
除了其他好的响应,还可以使用readpipe函数,相当于反引号和qx运算符。但与常规函数一样,您可以更好地控制其参数的插值方式。
$output = readpipe("mogrify -resize $wid" . "x$hit *.JPG");
$output = readpipe( sprintf "mogrify -resize %dx%d *.JPG", $wid, $hit );
Run Code Online (Sandbox Code Playgroud)