in reply to if -d

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';}]