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

Will someone help me understand what I am doing wrong?
bash: $ if [ -d /usr ]; then echo 'yes'; fi yes Perl 5.8.7 and 5.10 $ perl -le 'if (-d "/usr") { print 'yes';}'
thank you

Replies are listed 'Best First'.
Re: if -d
by FunkyMonk (Bishop) on Sep 03, 2009 at 15:36 UTC
    Quoting. Change the 'yes' to "yes"!
Re: if -d
by ikegami (Patriarch) on Sep 03, 2009 at 16:39 UTC

    In short, you tried to nest string quoted with single-quotes. That doesn't work. What follows is what bash see and how to fix the problem without changing what Perl sees.


    To form the string from the literal

    'if (-d "/usr") { print 'yes';}'

    bash extracts what's in single quotes and concatenates it with what's not in quotes. That means the following are concatenated together:

    1. if (-d "/usr") { print (not subject to interpolation and unescaping)
    2. yes (subject to interpolation and unescaping)
    3. ;} (not subject to interpolation and unescaping)

    Let's use Perl to see how bash sees the command:

    $ perl -le'print "[$_]" for @ARGV' -- \ perl -le 'if (-d "/usr") { print 'yes';}' [perl] [-le] [if (-d "/usr") { print yes;}]

    Compare with:

    'if (-d "/usr") { print '\''yes\''';}'
    1. if (-d "/usr") { print (not subject to interpolation and unescaping)
    2. \' (subject to interpolation and unescaping)
    3. yes (not subject to interpolation and unescaping)
    4. \' (subject to interpolation and unescaping)
    5. ;} (not subject to interpolation and unescaping)
    $ perl -le'print "[$_]" for @ARGV' -- \ perl -le 'if (-d "/usr") { print '\''yes'\'';}' [perl] [-le] [if (-d "/usr") { print 'yes';}]
Re: if -d
by Bloodnok (Vicar) on Sep 03, 2009 at 15:38 UTC
    Hmmm ,

    Missed it myself intially ...

    What you have is a quoting problem - try rewriting 'yes' to read "yes" ... or even q/yes/

    A user level that continues to overstate my experience :-))
Re: if -d
by ambrus (Abbot) on Sep 04, 2009 at 10:08 UTC

    Also, if you used the -w switch, perl would have given three warnings that together make the error clear.

    Unquoted string "yes" may clash with future reserved word at -e line 1 +. Name "main::yes" used only once: possible typo at -e line 1. print() on unopened filehandle yes at -e line 1.