rheaton has asked for the wisdom of the Perl Monks concerning the following question:

I can execute the following KSH from cmd line in unix.

gen_multi_seq.ksh "FAMP.001.DAT" '"FAMP.001.DAT"' "001" '"001"' "AMP_D +FR"

However when I try and execute the same thing in Perl using the following it fails. $grph_gen_multi_seq contains the path to and the gen_multi_seq.ksh value. This has been verified and is found correctly.

$return_val = system($grph_gen_multi_seq, "$data_source_contents[2]", +"\'\"$data_source_contents[2]\"\'", "$seq_num", "\'\"$seq_num\"\'", " +$data_source_contents[1]");

I have also tried...without success

$return_val = system($grph_gen_multi_seq, "\"$data_source_contents[2]\ +"", "\'\"$data_source_contents[2]\"\'", "\"$seq_num\"", "\'\"$seq_num +\"\'", "\"$data_source_contents[1]\"");

AND

$return_val = system($grph_gen_multi_seq, "\"".$data_source_contents[2 +]."\"", "\'\"$data_source_contents[2]\"\'", "\"".$seq_num."\"", "\'\" +$seq_num\"\'", ""\".$data_source_contents[1]."\"");

What am I doing wrong? OH, I also verified that the data in the read arrays is correct. Logically one of these should work. Thanks for your help!!

rheaton

Replies are listed 'Best First'.
Re: Execution KSH Script from Perl
by gaal (Parson) on Jan 18, 2007 at 20:26 UTC
    When you invoke it on the command line, your shell strips off the quotes. The ksh script doesn't see the "s in the first "FAMP.001.DAT", but does see them the second one precisely because they are quoted. (The same goes to for the other arguments.)

    So, in Perl, you don't need to do any special quoting since your invocation doesn't pass through an interactive shell. You don't need to do so much string interpolation inline, either; a clean way of adding the quotes is with a helper function. This should work:

    $return_val = system($grph_gen_multi_seq, $data_source_contents[2], myquote($data_source_contents[2]), $seq_num, myquote($seq_num), $data_source_contents[1]); # ... sub myquote { my($str) = @_; return "\"$str\""; }
      Rather than writing a subroutine to do the job, you could use Perl's quoting constructs. They also avoid the need to escape the double quotes you are wrapping around the string.

      $ perl -le ' > $seq_num = 1234; > $quoted_seq_num = qq{"$seq_num"}; > print qq{$seq_num - $quoted_seq_num};' 1234 - "1234" $

      The code would become

      $return_val = system($grph_gen_multi_seq, $data_source_contents[2], qq{"$data_source_contents[2]"}, $seq_num, qq{"$seq_num"}, $data_source_contents[1]);

      Cheers,

      JohnGG

Re: Execution KSH Script from Perl
by jhourcle (Prior) on Jan 18, 2007 at 20:18 UTC

    The shell is eating _some_ of the quote characters. As you're calling the system with multiple args, it's not passing it to your shell, and they're not being removed. Try the following:

    $return_val = system($grph_gen_multi_seq, $data_source_contents[2], "\"$data_source_contents[2]\"", $seq_num, "\"$seq_num\"", $data_source_contents[1]);

      I have tried that as well. The KSH is responding differently when it is called from the perl script like that and when it is run from the cmd line. Thanks for the thought though.

        That suggests that its environment is a little different (perhaps that it had loaded different startup scripts).

        Maybe your problem isn't with passing the arguments? If you can edit the ksh script, just add a debug dump of what it got and compare.

        It's likely then that you have more than one problem with your script, as the quoting one is blatant. However, you said you've verified the path and the values in the arguments, and I can't think of anything else that it might be, so I'd ask that you check again, using the following methods:

        First, make sure that the command runs from your script, by using backticks, so you can capture any messages:

        my $output = `gen_multi_seq.ksh "FAMP.001.DAT" '"FAMP.001.DAT"' "001" '"001"' "AMP_DFR" &2>1`;

        If it's a problem with pathing, this should hopefully give you a clue.

        Next, check to make sure that the values that the command you're generating is correct:

        warn <<EOF; system($grph_gen_multi_seq, "$data_source_contents[2]", "\'\"$data_sou +rce_contents[2]\"\'", "$seq_num", "\'\"$seq_num\"\'", "$data_source_c +ontents[1]"); EOF;

        If either of these two are the problem, and you correct them, I really do believe that the quoting issues with then be shown to be a problem, and you'll need to correct them as well.

Re: Execution KSH Script from Perl
by graff (Chancellor) on Jan 19, 2007 at 04:01 UTC
    When you do this at the command line:
    gen_multi_seq.ksh "FAMP.001.DAT" '"FAMP.001.DAT"' "001" '"001"' "AMP_D +FR"
    Your ksh script is being given 5 parameters, and those parameters are the following literal strings:
    FAMP.001.DAT "FAMP.001.DAT" 001 "001" AMP_DFR
    Note that if you provided a command line arg like  "'foo'" the shell script would get the literal paramter string  'foo'

    As you probably know already, there are many subtle details involved with the use of quotes in shell commands. In order to make sense of it all, it's essential to understand why the quotes are needed. You haven't given us any real clue about that. There's nothing in your sample ("working") shell command line that would appear to require any quotes at all -- unless the KSH script involves some sort of string editing (à la "sed", or something similar) where literal double-quotes are part of a replacement pattern.

    If you're getting into this much confusion about quotes, maybe you should rethink/refactor your process -- perl can probably do a lot more to rationalize and simplify it (e.g. use perl to do whatever the KSH script was supposed to do, and eliminate the KSH script completely). You're likely to end up with something that will be easier to maintain.