in reply to Re^2: Troubleshooting question
in thread Troubleshooting question

If you don't want any interpolation at all, use a temporary variable:
# single quotes prevent interpolation my $sed_command = 'sed -e :a -e "$d;N;2,3ba" -e "P;D" /db2/$DB2DBDFT/M +essages/temp.txt'; my $result = `$sed_command`; # passes a literal $d to sed, not the con +tents of the $d perl variable.
Perl 6 - links to (nearly) everything that is Perl 6.

Replies are listed 'Best First'.
Re^4: Troubleshooting question
by JavaFan (Canon) on Mar 23, 2010 at 16:56 UTC
    That's not going to work either. That code passes a literal $d to the shell. Use:
    my $sed_command = q{sed -e :a -e '$d;N;2,3ba' -e "P;D" /db2/$DB2DBDFT/ +Messages/temp.txt};
    From the rest of the code of the OP, I presume that the environment variable $DB2DBDFT is set, and that passing a literal $DB2DBDFT to the shell does the right thing.
      I have determined that the person that had written this script was being inefficient. They were running a db2 command putting the output into a variable then writing the variable to a file then reading the file and writing its contents into another file. I have shortened up the code and made it a little cleaner. I have gotten rid of the sed stuff completely and when I run it it does not give me any error message at all. Thank you to all of you for replying. Here is the snippet that I have changed: OLD:
      $bkp = `db2 "list history backup all for $db " |tail -6`; open TEMP, ">$temp"; print TEMP $bkp; close TEMP; print FILE "\nBackup Information:\n"; $bkp_info = `sed -e :a -e "{$d;N;2,3ba}" -e "{P;D}" /db2/$DB2DBDFT/Mes +sages/temp.txt`; if($bkp_info =~ /Start/) { print FILE $bkp_info; }
      NEW:
      $bkp = `db2 "list history backup all for $db " |tail -6`; print FILE "\nBackup Information:\n"; if($bkp =~ /Start/) { print FILE $bkp; }
      This new code saves 4 lines and doesn't give errors and the output via the email is still the same so I have no idea what the original programmer was doing with the sed command.
Re^4: Troubleshooting question
by elittle (Initiate) on Mar 23, 2010 at 17:17 UTC
    Just to clarify $d is NOT a perl variable it is a switch operator used by sed, which I believe is a regular exprssion type of command in UNIX/Linux. Also I believe there already is something similar to what you are proposing in the code already:
    $bkp_info = `sed -e :a -e "{$d;N;2,3ba}" -e "{P;D}" /db2/$DB2DBDFT/Mes +sages/temp.txt`;

    I am not sure if there is much difference in having the key word "my" in front of the variable that you have versus not having it. I have changed the backticks to double quotes and I have also tried using the curly braces as well in conjunction with and without backticks and/or double quotes all to no avail.

    I will try your suggestion and let you know the outcome. Thanks for replying. Could this be a bug?
      I am not sure if there is much difference in having the key word "my" in front of the variable that you have versus not having it

      That's not the crucial point.

      What's important is that I assign the contents, not the results of the backticks operation to a variable - and by doing that, I can use a different quoting constructor (single quotes).

      Could this be a bug?

      I don't see a bug; I just see a bug in your understanding of nested quoting constructs (which is not surprising, because three different ones appear: backticks, shell interpolation and shell interpolation in double-quoted strings).

      Perl 6 - links to (nearly) everything that is Perl 6.
        Thanks for clarifying my bug. Like I said I am coming in after someone and trying to clean up their code which had errors to begin with. I have tried it all ways with backticks without and every other permutation there of and when I used your code: my $sed_command = 'sed -e :a -e '$d;N;2,3ba' -e 'P;D' /db2/$DB2DBDFT/Messages/temp.txt'; I got this: Scalar found where operator expected at report.pl line 187, near "'sed -e :a -e '$d" (Missing operator before $d?) syntax error at report.pl line 187, near "'sed -e :a -e '$d" Bad name after ba' at report.pl line 187. Any who I got rid of that code plus 3 other lines and I get the same output from the email without any errors. This just illustrates the importance of commenting code because people come behind you and have to deal with your programs after you are long gone. Oops I couldn't my opinions to myself. THANK YOU to all of you that responded. I appreciate your help and explanations.
      Also I believe there already is something similar to what you are proposing in the code already:
      $bkp_info = `sed -e :a -e "{$d;N;2,3ba}" -e "{P;D}" /db2/$DB2DBDFT/Mes +sages/temp.txt`;
      Similar on first appearance, but fundamentally different.

      As far as Perl is concerned, (and Perl goes first, then the shell, and only then it's seds turn), in the above line, $d is Perl variable. If you want to pass $d to shell you first need to protect against Perl, then against the shell. The above code does neither. In:

      my $cmd = q{sed -e :a -e '{$d;N;2,3ba}' -e "{P;D}" /db2/$DB2DBDFT/Mess +ages/temp.txt}; $bkp_info = `$cmd`;
      the $d to protected against both. The q{} construct makes Perl not interpolate variables (unlike the backticks). And the single quotes makes the shell not interpolate variables (unlike the double quotes).