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

Why doesn't this print anything in log.txt
$abc = `date`; print "DATE : $abc\n"; system("echo $abc >> log.txt");
while this does...
$abc = "Hello"; print "DATE : $abc\n"; system("echo $abc >> log.txt");

Replies are listed 'Best First'.
Re: system call with variable interpolation
by JavaFan (Canon) on Jul 15, 2011 at 11:20 UTC
    Because in the first, $abc will contain a newline, which for the shell is a statement separator?
      ok... but how do i make it do what i want!!!!
        Some options:
        • Remove the newline.
        • Escape anything special to the shell.
        • Don't use the shell to do something Perl can do trivially.
        • Do it all in the shell. (date >> log.txt)
        Try:
        system("echo \'$abc\' >> log.txt");
Re: system call with variable interpolation
by TomDLux (Vicar) on Jul 15, 2011 at 16:58 UTC

    When I come across strange behaviour such as this, there are a number of things I do automatically to determine why perl's interpration of what to do ( or the shell's interpretation ) differs from mine. They're supposed to DWIM!!

    I start by adding use warnings; use strict at the top, which in a short stub such as this I might not have. On the other hand, presumably the stub was created to decipher odd behaviour in a larger program, in which case the strictures would be the first thing I type.

    Calling system() with strings generated in place invites surprises. I always break it out into the definition of the string, assigned to a variable; logging the variable; and then invoking the command.

    System calls need to have their return status checks. Of course program invocation returns notification of errors, rather than success, so the logic is reversed from what you would like.

    my $cmd = "echo $abc >> log.txt"; print "cmd is $cmd\n"; system( $cmd ) == 0 or die( "Error in system() call: $?.\n" );

    Which prints out:

    echo Fri Jul 15 12:41:31 EDT 2011 >> log.txt

    At this point I noticed the date needed to have the newline chomped off, after which program succeeded.

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Re: system call with variable interpolation
by Bloodnok (Vicar) on Jul 15, 2011 at 11:30 UTC
    Hmmm, seems to work for me, aren't I lucky :-)
    # perl -e '$d=`date`;system "echo \"d: $d\">t"' # more t d: Fri Jul 15 13:54:50 BST 2011 #
    A user level that continues to overstate my experience :-))
      Hmmm, seems to work for me, aren't I lucky
      But you're doing something else. You've added quotes.
      put it in a file with #!/usr/bin/perl -- and it probably won't work -- your shell probably sets/expands $d before your perl program runs
        Not true - if you notice, the 'program' is in single quotes - which has the same effect in the shell as it does in a perl program i.e. variables aren't expanded.

        A user level that continues to overstate my experience :-))
Re: system call with variable interpolation
by Anonymous Monk on Jul 15, 2011 at 12:01 UTC

    Worked in both cases here (CentOS 5, zsh 4) ...

    #!~/bin/perl5.14.1 use strict; use warnings; my $abc; $abc = `date`; #$abc = "Hello"; print "DATE : $abc\n"; system("echo $abc >> log.txt");

      ... even without the pragmas & declaration of the variable ...

      cat ~/p ; rm -f log.txt ; ~/p ; cat log.txt #!~/bin/perl5.14.1 $abc = `date`; #$abc = "Hello"; print "DATE : $abc\n"; system("echo $abc >> log.txt"); __END__ DATE : Fri Jul 15 02:07:45 HST 2011 Fri Jul 15 02:07:45 HST 2011
      ... I note just in case somebody wanted to nit pick.
Re: system call with variable interpolation
by Anonymous Monk on Jul 16, 2011 at 20:31 UTC
    You need to use "": $abc = `date`; print "DATE : $abc\n"; system("echo \"$abc\" >> log.txt");