How do I use a perl variable name properly within backticks?

前端 未结 3 599
心在旅途
心在旅途 2020-12-30 04:01

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

mogrify -resize 800x600 *JPG

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

3条回答
  •  长发绾君心
    2020-12-30 04:09

    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.

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

    my $genes = "ACTG$insert_genes_hereACTG";
    

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

    1. Using curlies to delimit the name:

      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:

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

      A variant of this is to use sprintf interpolation:

      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).

    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.

提交回复
热议问题