[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Jul 8 13:08:57 1999 
Subject:Re: running unix program from pop11 
From:"Stephen F. K. Leach" 
Volume-ID:990708.01 

Hi,

This must be one of the commonest requests - and it is something of
a mystery to me why Poplog does not provide some nice "poppish"
interfaces.  We have sysobey, piputils, and run_unix_program - but
they are either simple-but-inflexible or complex-but-useless.

Here are some ideas for making idiomatic UNIX programming more
straightforward.  The first part of the message is about enhancing
or replacing -sysobey- with a new procedure called -system-.  The
second part discusses making environment variables simpler.

Ideas for -sysobey/system-
--------------------------

I'd like to see the following enhancement to -sysobey-, or possibly
a replacement called -system-.  I have made up an optional argument
syntax which I hope is more or less obvious since this is the kind
of procedure that cries out for optional arguments in my view.

1.  -system- should be a synonym for -sysobey- or an enhanced version
    of -sysobey-.  All C + Perl + UNIX programmers know this command
    by this name and I can see no merit in being different.  At the very
    least, the documentation should support programmers looking for it
    by this name.

2.  It should be possible to explicitly select the shell
    used to execute the command.  These days there are rather more
    popular shells than just sh and csh!

    As an aside, we really should consider introducing
    optional argument syntax to do this sort of thing.  Here is a
    badly thought-out syntax which I'll use to illustrate some
    ideas throughout the rest of this letter.  e.g.
        system[ shell = '/bin/tcsh' ]( 'ls' )
    where the new syntax
        f[ word = <expr>, ... ]
    introduces a specialisation of "f" with the options of that procedure
    set appropriately.  I would also expect that it would be OK to
    write
        f[ foo=a, bar=b ][ gort=c ]
    i.e. that you can cascade optional arg lists.

    I will write a follow-up message about how this can be done efficiently.

    Option shell = <string>

3.  It should be possible to capture the result of the command in
    a file/character-repeater/device.  (Similarly stderr.)  Note
    that the keyword "device" would mean return a device from which
    output can be read.  The keyword "chars" would mean return a
    character repeater.  The keyword "string" would mean return the
    output as a string.  The keyword "lines" would return a line
    repeater and "list" a list of lines.

    Option output = <string|"string"|"chars"|"lines"|"list"|"device"|device>
           errput = <string|"string"|"chars"|"lines"|"list"|"device"|device>

4.  It should be possible to supply the command with a standard input
    that is drawn from a file/list/repeater/device.  Note that
    "device" would mean return a device from to which input can be
    written.  The repeater would be allowed to return strings or
    characters.  Similarly true for a list.

    Option input = <string|procedure|"device"|device>

3.  It should be possible to execute sysobey in the background i.e. there
    should be an optional wait flag i.e. the general calling interface would
    be
        sysobey( <command:string>, <shell:char>, <wait:boolean> )
     with two optional parameters.  -wait- would default to -true-.  If
     my "demo" optional argument syntax is adopted the interface would be
     written as
        system[
            shell = <string>,
            wait = <boolean>,
            output = <string|"string"|"chars"|"lines"|"list"|"device"|device>
            input = <string|"string"|"chars"|"lines"|"list"|"device"|device>
        ](
            <command:string> | <file:string>, <args:list>
        ) -> [ <input> ] [ <output> ] [ <errput> ]

5.  I would like the default shell of -sysobey- to be explicitly
    changed to /bin/bash (whenever available).  It is pretty much
    exclusively used under Linux.

I would imagine that one of the commonest uses would be
commands such as

    system[ output="repeater", input=my_repeater ]( 'grep -v foo' ) -> rep;

where the output and input parameters are bound.  This would create
an output repeater that would automatically invoke the input repeater
on demand.  Also common would be

    system[ output="list" ]( 'find . -type f' ) -> list_of_lines
and
    system[ output="string" ]( 'uname -a' ) -> uname_string


Shorthand
---------

I think that the $( ... ) brackets in /bin/bash are a very
useful shorthand - these are used for getting the output of a command
as a string e.g.

    system[ output="string" ]( 'uname -a' )

could be written as

    $( 'uname -a' )

In this case, I would see "$( ... )" as a syntactic shorthand for

    system[ output = "string" ]( ... )



Using Environment Variables
---------------------------

In addition, there are a variety of UNIX idioms that are very
common and I believe UNIX versions of Poplog should support.  For
example "$" for accessing environment variables is something that
I have been using for years in my local library to good effect.
One mistake is that my version does not recognise ${foo} as
identical to $foo.  Here's a quick hack that remedies that ...

compile_mode :pop11 +strict;

section;

define global syntax $ ;
    lvars it = readitem();
    if it == "{" then
        readitem() -> it;
        pop11_need_nextreaditem( "}" ).erase;
    endif;
    sysPUSHQ( it sys_>< nullstring );
    sysCALL -> pop_expr_inst;
    "systranslate" -> pop_expr_item;
enddefine;

endsection;

Using this syntax word, you can access and update variables in a
way that is very natural to UNIX programmers.  e.g.

    $TERM =>
    ** linux

    'vt100' -> $TERM;


                           ---oooOOOooo---

Of course, these are just ideas.  I would very much like to be able
to program using these facilities - and I definitely would find a
general and efficient optional argument syntax invaluable.  What
do others think?

Steve