in reply to Re: Troubleshooting question
in thread Troubleshooting question

$DB2DBFT is an evironment variable that is in the env file. $d is a swtich that is used with sed. I saw on another site where they had the switches inside '{switches}', so I tried that format but it still generated the error. Thanks for replying.

Replies are listed 'Best First'.
Re^3: Troubleshooting question
by moritz (Cardinal) on Mar 23, 2010 at 16:29 UTC
    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.
      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.
      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.
        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).