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

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.这可以通过以下方式解决

  1. 使用curlies来分隔名称:

    my $genes = "ACTG${insert_genes_here}ACTG";
    
    Run Code Online (Sandbox Code Playgroud)

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

  2. 连接字符串:

    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不止一个论点也是如此.


Dav*_*oss 5

此问题并非特定于反引号.每当您在字符串中插入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)


mob*_*mob 5

除了其他好的响应,还可以使用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)