home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / rexx / 706 < prev    next >
Encoding:
Text File  |  1992-08-13  |  6.5 KB  |  156 lines

  1. Newsgroups: comp.lang.rexx
  2. Path: sparky!uunet!mcsun!sunic!aun.uninett.no!ugle.unit.no!ugle!anders
  3. From: anders@lise7.lise.unit.no (Anders Christensen)
  4. Subject: Re: SH backquote functionality in REXX?
  5. In-Reply-To: jbthiel@ogicse.ogi.edu's message of 13 Aug 92 04:33:47 GMT
  6. Message-ID: <ANDERS.92Aug13173056@lise7.lise.unit.no>
  7. Sender: news@ugle.unit.no (NetNews Administrator)
  8. Organization: /home/flipper/anders/.organization
  9. References: <41280@ogicse.ogi.edu>
  10. Date: 13 Aug 92 17:30:56
  11. Lines: 143
  12.  
  13. In article <41280@ogicse.ogi.edu> jbthiel@ogicse.ogi.edu (John B. Thiel) writes:
  14.  
  15. > What, if any, is a Rexx equivalent to the backquote mechanism as used
  16. > in SH, whereby `process` is replaced by the stdio output of the
  17. > process?
  18. >
  19. > eg.
  20. > now=`date`
  21.  
  22. There aren't a Rexx equivalent, there are probably several, depending
  23. on the Rexx implementation that you are using. According to "The REXX
  24. Language" by M.F. Cowlishaw, Rexx allows external functions which may
  25. be an external program, written in Rexx or in any other language that
  26. "supports the implementation-dependent interfaces used by REXX to
  27. invoke it." It is the duty of the command to be able to communicate
  28. with the interpreter, not the other way around. 
  29.  
  30. So the only thing that you are guaranteed, is that if the external
  31. program that you want to invoke is a Rexx script, then it will work.
  32. If it is not a Rexx script, then the behavior is implementation
  33. dependent. Sorry ... 
  34.  
  35. However, DON'T PANIC! Most implementation has some way to do this. The
  36. ways differ, so it is hard to write compatible Rexx scripts to do
  37. this. 
  38.  
  39. Let's take an example:
  40.  
  41.    Suppose you want to run the command 'hostname', which just writes
  42.    out the name of the machine that you are using as output. The
  43.    following *might* work:
  44.  
  45.       say 'My host is' hostname()
  46.  
  47.    Supposing that there are no labels called 'hostname' and no builtin
  48.    functions called 'hostname'. It also requires that the command in
  49.    your operating system can be accessed as "HOSTNAME" (Rexx always
  50.    upper case unquoted names). If you use:
  51.  
  52.       say 'My host is' 'hostname'()
  53.  
  54.    It will work if there are no builtin function called 'hostname' and
  55.    that the external function can be found using the name 'hostname'
  56.    (note the lower case letters). 
  57.  
  58. In both these cases, you are only guaranteed success if 'hostname' is an
  59. external Rexx program, if it is something else (let's say a compiled C
  60. program), then you're at the mercy of the implementation. 
  61.  
  62. So, back to your example. You wanted to get output from the operating
  63. system command 'date'. This is a real trap, for several reasons.
  64.  
  65. 1) The clause   say 'DATE'()   will call the Rexx builtin function 
  66.    date() in rexx, so you cat at least *never* use that.
  67.  
  68. 2) The clause say 'date'() will *never* call the builtin function
  69.    date() in rexx. But (depending on your opsys) it might not be the
  70.    right case for the command to call (i.e. 'date' != 'DATE'). Since
  71.    you are referring to the Bourne shell, I assume that you are using
  72.    Unix, and then the lower case letters is exactly what you need.
  73.  
  74. 3) At least on Unix systems, there might be a way around it, by using
  75.    a path, and calling it as  '/bin/date'(). Then you will never crash
  76.    into a builtin function.
  77.  
  78. 4) On some systems certain command are 'builtin' in the external
  79.    environment. Under Unix there are 'echo', 'time' and 'umask'; Under
  80.    MS-DOS there are 'echo', 'time' and 'date', just to mention a few. 
  81.    Whether or not you are able to reach these function depends
  82.    completely on the implementation. 
  83.  
  84. 5) Then there is the problem of sending parameters. At least on Unix
  85.    machines, the command gets its parameter string chopped up in
  86.    individual parameters. Let's assume that you want to run the
  87.    command 'who' with the two parameters 'am' and 'I'. (A unix command
  88.    that writes out you user name and a few other things.) Depending on
  89.    the implementation, there are several ways to do this, e.g.
  90.  
  91.       say 'who'('am', 'I')   /* type one */
  92.       say 'who'('am I')      /* type two */
  93.  
  94.    The first type is the 'correct' Rexx way to do it: Run 'who' with
  95.    the two parameters 'am' and 'I', but it looks kind of ugly. The
  96.    second type is more readable, but you depend on implicit rules for
  97.    deciding where to divide the parameters (suppose you wanted a
  98.    parameter containing a space?). 
  99.  
  100.    Actually, a type one interpreter getting a type two call, would
  101.    call 'who' with the single parameter 'am I'. A type two interpreter
  102.    getting a type one call might be capable to trap it and do the
  103.    right thing. 
  104.  
  105.    To confuse even more ... the whole thing might also be dependent on
  106.    which interface is used when calling the command. If it is called
  107.    through a command interpreter, the second type call on a first type
  108.    interpreter might work after all, since the command interpreter
  109.    will parse the parameters.  (Then, even say  'who am I'()  would
  110.    work). 
  111.  
  112. 6) Unfortunately (or maybe fortunately), there are really no
  113.    requirements in TRL that specify how external command are going to
  114.    be interpreted. In fact, there is not even any grounds to claim
  115.    that the ADDRESS clause will effect the choice of what environment
  116.    functions are sent to.
  117.    
  118. That was the first method. The second method, which may (or may not)
  119. work if the first method does not work, is to run the command and
  120. flush the output to the stack, an then pull the result that you want. 
  121. Unfortunately, there are even more problems in this area ...
  122.  
  123. 1) Most operating system don't know of the concept of a stack, so in
  124.    some Rexx interpreters there are kludged in ways to redirect the
  125.    output and input to and from the stack. In REXX/imc you would do
  126.    something like
  127.  
  128.       'date | rxstack'
  129.       parse pull line
  130.  
  131.    while in Regina, you would do something similar (in syntax):
  132.  
  133.       'date >LIFO'
  134.       parse pull line
  135.  
  136.    and in other rexx interpreters, you would probably do it in some
  137.    other manner.
  138.  
  139. 2) Interpreters that don't kludge the stack concept into their
  140.    commands, may use another strategy, like that of uni-REXX, which
  141.    uses the function popen() to run a command with output to the
  142.    stack. The parameter of popen() is the command to run, like:
  143.  
  144.       junk = popen('date')
  145.       parse pull line 
  146.  
  147. 3) Some operating systems that *do* know the stack concept, often
  148.    offer options to their commands, like CMS's '(STACK' or '(LIFO'
  149.    which enables the user to request that the output from that command
  150.    is put on the stack. 
  151.  
  152. If you really want to write compatible code, you'll probably want to
  153. avoid the whole problem, and just use the builtin function date(). 
  154.  
  155. -anders
  156.