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

时间:2021-10-24 04:50:09

I need to execute the following code on a bash shell:

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

mogrify -resize 800x600 *JPG

Since the width and height are variables, I tried this:

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

`mogrify -resize $widx$hit *JPG`

However in compilation, I get the error that Global symbol "$widx" requires explicit package name at getattach.pl line 131., which is because instead of $wid and x seperately, the compiler sees $widx as a new undeclared variable.

但是在编译时,我得到的错误是全局符号“$ widx”在getattach.pl第131行需要显式包名,这是因为编译器将$ widx视为新的未声明变量而不是$ wid和x。

I tried inserting double quotes inside the backticks, but execution of code stopped without any messages.

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

What's the proper way of inserting variable names in backticks for shell execution? Can they be concatenated?

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

3 个解决方案

#1


20  

To insert a variable into any interpolating string (be it qq// or qx or qr//), just doing "this is $foo!" is sufficient: The variable name (here: $foo) is delimited by the ! which cannot be part of a normal variable name.

要将变量插入任何插值字符串(无论是qq //还是qx或qr //),只需执行“this is $ foo!”足够了:变量名称(这里:$ foo)由!分隔!它不能是普通变量名的一部分。

It is not so easy when parts of the string could be part of the name by Perl's naming rules. Example:

如果字符串的某些部分可能是Perl命名规则的名称的一部分,那就不那么容易了。例:

my $genes = "ACTG$insert_genes_hereACTG";

Perl considers the variable name to be $insert_genes_hereACTG. This can be solved by

Perl认为变量名称为$ insert_genes_hereACTG。这可以通过解决

  1. Using curlies to delimit the name:

    使用curlies来分隔名称:

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

    This always works and is a flexible solution

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

  2. Concatenating the string:

    连接字符串:

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

    This is a bit difficult for non-qq-quotes. A solution is to create a temporary variable that holds the whole string, and then interpolates it into special quotes:

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

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

    A variant of this is to use sprintf interpolation:

    其中一个变体是使用sprintf插值:

    my $command = sprintf 'mogrify -resize %dx%d *JPG', $wid, $hit;
    

As an aside, many shell interpolation problems can be circumvented by not using backticks, and using open or system instead (depending on whether or not you need output).

顺便说一句,许多shell插值问题可以通过不使用反引号,使用open或system来取决(取决于你是否需要输出)。

With open:

随着开放:

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

while (<$command>) { do something }

This completely circumvents the shell (and rather execs directly), so globbing has to be done manually. The same holds true for system with more than one argument.

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

#2


5  

This problem isn't specific to backticks. The problem can happen whenever you interpolate Perl variables in a string.

此问题并非特定于反引号。每当您在字符串中插入Perl变量时,就会发生此问题。

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

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

The problem is that the Perl compiler can't know where the variable name ("wid") ends and the fixed bit of the string ("x") starts. So it assumes that it is looking for a variable called $widx - which doesn't exist.

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

The solution is to put the name of the variable in { ... }.

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

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

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

#3


1  

In addition to the other good responses, you can also use the readpipe function, which is equivalent to backticks and the qx operator. But like a regular function, you can exercise greater control over how the arguments to it are interpolated.

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

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

#1


20  

To insert a variable into any interpolating string (be it qq// or qx or qr//), just doing "this is $foo!" is sufficient: The variable name (here: $foo) is delimited by the ! which cannot be part of a normal variable name.

要将变量插入任何插值字符串(无论是qq //还是qx或qr //),只需执行“this is $ foo!”足够了:变量名称(这里:$ foo)由!分隔!它不能是普通变量名的一部分。

It is not so easy when parts of the string could be part of the name by Perl's naming rules. Example:

如果字符串的某些部分可能是Perl命名规则的名称的一部分,那就不那么容易了。例:

my $genes = "ACTG$insert_genes_hereACTG";

Perl considers the variable name to be $insert_genes_hereACTG. This can be solved by

Perl认为变量名称为$ insert_genes_hereACTG。这可以通过解决

  1. Using curlies to delimit the name:

    使用curlies来分隔名称:

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

    This always works and is a flexible solution

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

  2. Concatenating the string:

    连接字符串:

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

    This is a bit difficult for non-qq-quotes. A solution is to create a temporary variable that holds the whole string, and then interpolates it into special quotes:

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

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

    A variant of this is to use sprintf interpolation:

    其中一个变体是使用sprintf插值:

    my $command = sprintf 'mogrify -resize %dx%d *JPG', $wid, $hit;
    

As an aside, many shell interpolation problems can be circumvented by not using backticks, and using open or system instead (depending on whether or not you need output).

顺便说一句,许多shell插值问题可以通过不使用反引号,使用open或system来取决(取决于你是否需要输出)。

With open:

随着开放:

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

while (<$command>) { do something }

This completely circumvents the shell (and rather execs directly), so globbing has to be done manually. The same holds true for system with more than one argument.

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

#2


5  

This problem isn't specific to backticks. The problem can happen whenever you interpolate Perl variables in a string.

此问题并非特定于反引号。每当您在字符串中插入Perl变量时,就会发生此问题。

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

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

The problem is that the Perl compiler can't know where the variable name ("wid") ends and the fixed bit of the string ("x") starts. So it assumes that it is looking for a variable called $widx - which doesn't exist.

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

The solution is to put the name of the variable in { ... }.

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

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

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

#3


1  

In addition to the other good responses, you can also use the readpipe function, which is equivalent to backticks and the qx operator. But like a regular function, you can exercise greater control over how the arguments to it are interpolated.

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

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