home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / perl / 6879 < prev    next >
Encoding:
Text File  |  1992-11-08  |  4.1 KB  |  89 lines

  1. Path: sparky!uunet!charon.amdahl.com!pacbell.com!ames!saimiri.primate.wisc.edu!zaphod.mps.ohio-state.edu!usc!news!netlabs!lwall
  2. From: lwall@netlabs.com (Larry Wall)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: explanation of the camel book code needed
  5. Keywords: sh csh perl ksh running with shells
  6. Message-ID: <1992Nov6.232609.24722@netlabs.com>
  7. Date: 6 Nov 92 23:26:09 GMT
  8. References: <1992Nov5.123219.16031@unilabs.uucp>
  9. Organization: NetLabs, Inc.
  10. Lines: 77
  11.  
  12. The code in question is something like
  13.  
  14.     eval '(exit $?0)' && eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
  15.     & eval 'exec /usr/bin/perl -S $0 $argv:q'
  16.     if 0;
  17.  
  18. The interpretation by sh:
  19.  
  20.     '(exit $?0)' is a single-quoted string, and is passed to eval unchanged.
  21.     eval processes the string:
  22.     () forks a subshell and executes the command inside.
  23.     $? returns 0 because there was no last command to return status from.
  24.     $?0 interpolates to 00.
  25.     exit 00 exits the subshell with a 0 status, setting $? in our shell.
  26.     && evaluates the $? set by the left side, and since it's 0, evaluates
  27.       the right side.
  28.     'exec /usr/bin/perl -S $0 ${1+"$@"}' is a single-quoted string, and is
  29.       passed to eval unchanged.
  30.     eval processes the string:
  31.     $0 is interpolated to be the current script name.  On some systems
  32.       this will be a fully qualified pathname, and on others it'll be
  33.       just the filename.
  34.     $1 is evaluated, and if set, "$@" is interpolated, passing all the
  35.       passing all the arguments into the perl command.  If not set,
  36.       nothing is interpolated.  (This is a workaround for an sh bug,
  37.       in which "$@" interpolates an unwanted "" if there are no arguments.
  38.       We use "$@" rather than $* because $* doesn't properly quote
  39.       filenames containing spaces and such.)
  40.     /usr/bin/perl is executed.  The -S tells perl to look for $0 in
  41.       the path if $0 isn't a fully qualified pathname.
  42.     The last two lines remain unevaluated because we did an exec.
  43.     
  44. The interpretation by csh:
  45.  
  46.     '(exit $?0)' is a single-quoted string, and is passed to eval unchanged.
  47.     eval processes the string:
  48.     () forks a subshell and executes the command inside.
  49.     $?0 interpolates 1 because the $0 variable is set.
  50.     exit 1 exits the subshell with a 1 status, setting $status in our shell.
  51.     && evaluates the $status set by the left side, and since it's 1, does NOT
  52.       evaluate the right side, but procedes to the next statement.
  53.     The & on the next line is ignored because there's a null command before it.
  54.     'exec /usr/bin/perl -S $0 $argv:q' is a single-quoted string, and is
  55.       passed to eval unchanged.
  56.     eval processes the string:
  57.     $0 is interpolated to be the current script name.
  58.     $argv:q is interpolated to be the current arguments, with a modifier
  59.       that says to pretend they were all quoted.
  60.     /usr/bin/perl is executed.  The -S tells perl to look for $0 in
  61.       the path if $0 isn't a fully qualified pathname.
  62.     The last line remains unevaluated because we did an exec.
  63.  
  64. The interpretation by perl:
  65.  
  66.     The entire program is parsed first, so all three lines are parsed as
  67.       one expression statement with a modifier.  The first two lines are the
  68.       expression.  We now see that the & on the second line is there merely
  69.       to tie the two lines together into a single Perl expression--it wouldn't
  70.       matter what it is as long as csh ignores it.
  71.     The Perl program is executed.  The statement modifier is false, so
  72.       the entire statement is skipped.  It doesn't matter at all to Perl
  73.       what the syntax of the expression in the first two lines is, as
  74.       long as it comes out to a single expression.
  75.  
  76. The main clinker in this is that there are Certain Vendors who have
  77. been peddling, since time immemorial, a brain-dead version of csh
  78. (I ask myself, was there ever a brain-live version of csh?) that
  79. reverses the meanings of && and ||.  On *some* of these machines, you
  80. can prefix the above with a line that reads
  81.  
  82.     "true" || eval 'exec /usr/bin/perl -S $0 $argv:q';
  83.  
  84. Unfortunately, some systems are so far gone that their csh doesn't
  85. even have an eval.  In such cases, immediate and radical amputation of
  86. the power cord is the only recourse.
  87.  
  88. Larry
  89.