home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.rexx
- Path: sparky!uunet!mcsun!sunic!aun.uninett.no!ugle.unit.no!ugle!anders
- From: anders@lise7.lise.unit.no (Anders Christensen)
- Subject: Re: SH backquote functionality in REXX?
- In-Reply-To: jbthiel@ogicse.ogi.edu's message of 13 Aug 92 04:33:47 GMT
- Message-ID: <ANDERS.92Aug13173056@lise7.lise.unit.no>
- Sender: news@ugle.unit.no (NetNews Administrator)
- Organization: /home/flipper/anders/.organization
- References: <41280@ogicse.ogi.edu>
- Date: 13 Aug 92 17:30:56
- Lines: 143
-
- In article <41280@ogicse.ogi.edu> jbthiel@ogicse.ogi.edu (John B. Thiel) writes:
-
- > What, if any, is a Rexx equivalent to the backquote mechanism as used
- > in SH, whereby `process` is replaced by the stdio output of the
- > process?
- >
- > eg.
- > now=`date`
-
- There aren't a Rexx equivalent, there are probably several, depending
- on the Rexx implementation that you are using. According to "The REXX
- Language" by M.F. Cowlishaw, Rexx allows external functions which may
- be an external program, written in Rexx or in any other language that
- "supports the implementation-dependent interfaces used by REXX to
- invoke it." It is the duty of the command to be able to communicate
- with the interpreter, not the other way around.
-
- So the only thing that you are guaranteed, is that if the external
- program that you want to invoke is a Rexx script, then it will work.
- If it is not a Rexx script, then the behavior is implementation
- dependent. Sorry ...
-
- However, DON'T PANIC! Most implementation has some way to do this. The
- ways differ, so it is hard to write compatible Rexx scripts to do
- this.
-
- Let's take an example:
-
- Suppose you want to run the command 'hostname', which just writes
- out the name of the machine that you are using as output. The
- following *might* work:
-
- say 'My host is' hostname()
-
- Supposing that there are no labels called 'hostname' and no builtin
- functions called 'hostname'. It also requires that the command in
- your operating system can be accessed as "HOSTNAME" (Rexx always
- upper case unquoted names). If you use:
-
- say 'My host is' 'hostname'()
-
- It will work if there are no builtin function called 'hostname' and
- that the external function can be found using the name 'hostname'
- (note the lower case letters).
-
- In both these cases, you are only guaranteed success if 'hostname' is an
- external Rexx program, if it is something else (let's say a compiled C
- program), then you're at the mercy of the implementation.
-
- So, back to your example. You wanted to get output from the operating
- system command 'date'. This is a real trap, for several reasons.
-
- 1) The clause say 'DATE'() will call the Rexx builtin function
- date() in rexx, so you cat at least *never* use that.
-
- 2) The clause say 'date'() will *never* call the builtin function
- date() in rexx. But (depending on your opsys) it might not be the
- right case for the command to call (i.e. 'date' != 'DATE'). Since
- you are referring to the Bourne shell, I assume that you are using
- Unix, and then the lower case letters is exactly what you need.
-
- 3) At least on Unix systems, there might be a way around it, by using
- a path, and calling it as '/bin/date'(). Then you will never crash
- into a builtin function.
-
- 4) On some systems certain command are 'builtin' in the external
- environment. Under Unix there are 'echo', 'time' and 'umask'; Under
- MS-DOS there are 'echo', 'time' and 'date', just to mention a few.
- Whether or not you are able to reach these function depends
- completely on the implementation.
-
- 5) Then there is the problem of sending parameters. At least on Unix
- machines, the command gets its parameter string chopped up in
- individual parameters. Let's assume that you want to run the
- command 'who' with the two parameters 'am' and 'I'. (A unix command
- that writes out you user name and a few other things.) Depending on
- the implementation, there are several ways to do this, e.g.
-
- say 'who'('am', 'I') /* type one */
- say 'who'('am I') /* type two */
-
- The first type is the 'correct' Rexx way to do it: Run 'who' with
- the two parameters 'am' and 'I', but it looks kind of ugly. The
- second type is more readable, but you depend on implicit rules for
- deciding where to divide the parameters (suppose you wanted a
- parameter containing a space?).
-
- Actually, a type one interpreter getting a type two call, would
- call 'who' with the single parameter 'am I'. A type two interpreter
- getting a type one call might be capable to trap it and do the
- right thing.
-
- To confuse even more ... the whole thing might also be dependent on
- which interface is used when calling the command. If it is called
- through a command interpreter, the second type call on a first type
- interpreter might work after all, since the command interpreter
- will parse the parameters. (Then, even say 'who am I'() would
- work).
-
- 6) Unfortunately (or maybe fortunately), there are really no
- requirements in TRL that specify how external command are going to
- be interpreted. In fact, there is not even any grounds to claim
- that the ADDRESS clause will effect the choice of what environment
- functions are sent to.
-
- That was the first method. The second method, which may (or may not)
- work if the first method does not work, is to run the command and
- flush the output to the stack, an then pull the result that you want.
- Unfortunately, there are even more problems in this area ...
-
- 1) Most operating system don't know of the concept of a stack, so in
- some Rexx interpreters there are kludged in ways to redirect the
- output and input to and from the stack. In REXX/imc you would do
- something like
-
- 'date | rxstack'
- parse pull line
-
- while in Regina, you would do something similar (in syntax):
-
- 'date >LIFO'
- parse pull line
-
- and in other rexx interpreters, you would probably do it in some
- other manner.
-
- 2) Interpreters that don't kludge the stack concept into their
- commands, may use another strategy, like that of uni-REXX, which
- uses the function popen() to run a command with output to the
- stack. The parameter of popen() is the command to run, like:
-
- junk = popen('date')
- parse pull line
-
- 3) Some operating systems that *do* know the stack concept, often
- offer options to their commands, like CMS's '(STACK' or '(LIFO'
- which enables the user to request that the output from that command
- is put on the stack.
-
- If you really want to write compatible code, you'll probably want to
- avoid the whole problem, and just use the builtin function date().
-
- -anders
-