[comp.sys.amiga] Pipes

keithe@tekgvs.UUCP (Keith Ericson) (01/20/87)

I post the following that I scarfed off the net a long time ago with
profound apologies for having discarded the originator's identity (step
forward and identify yourself if you want).

I've never verified whether it works or not - caveat emptor:

***********************************************************************

Guess what.  You can use "pipes" on the Amiga to pipe the output of one
process to the input of another.  This requires:

	no C code
	no programming knowlege
	the enclosed execute file.

While AndyF and I were discussing the spool execute files he remarked,
"You know, this means we can do pipes!" (Not a direct quote, but that
was the spirit of the thing.)

Well I gave it some thought and agreed.  Then I wrote the following
execute file.  It works.

Copies of this file (hardcopy) were passed out at last nights BADGE
meeting at SRI, Menlo Park.  Enjoy!!


Comments about the PIPE execute file:

1) Command syntax:
	EXECUTE PIPE command_1 arg1 argn | command_2 arg1 argn

2) This version allows a total of two (2) commands (or programs) and 
	eight (8) arguments.  The arguments may be used by either command,
	or both in any combination.  The execute file could be expanded
	to handle more options.

3) Sample usage:
	EXECUTE PIPE echo "20-Feb-86" | date "?"
	EXECUTE PIPE dir | more
	EXECUTE PIPE dir df1: opt a | more

4) All of this will work faster if you run it out of RAM:.

5) Almost none of the AmigaDOS commands use standard input if no 
	parameters are given.  This is a problem which should be
	addressed.

6) It would be even more convenient if we did not have to eliminate stray
	parameters from the end of the line (we could delete lines 17-41
	and line 44) but for the first example I used (see # 3 above)
	this will not work.  If the DATE command detects characters
	past its last parameter (even spaces) it displays "Bad Args".

7) Comments referring to the execute file by line number:
	Line 1, define 11 optional arguments.  Actually c1, c2, and c3
	could be made required.
	
	lines 3 and 4, redefine the bracketing characters (the default
	is "<" and ">" but these are needed for redirection).
	
	Lines 1, 6, 11 and 51, the parameter FLAG is intended for internal
	use only.  The used should not specify it.  The FLAG parameter is
	used to determine the state of the execute file, as follows:
		FLAG = "", the user just executed this file.
		FLAG = "is|?", we are looking for c2 to match the "|"
			(pipe character).
		FLAG = "DoIt", c1 and c2 are set up for running, run them
			and delete the intermediate pipe file (RAM:PIPE$$$)
	
	Lines 6-9, This is the first time we've been called, change c1
	to redirect its output to the pipe file.
	
	Lines 11-49, What to do if we are still looking for the "|" character.
	
	Lines 12-15, What to do if we never find the "|" character, and
	run out of parameters looking for it.
	
	Lines 16-48, We've found the "|" character so let's call our self
	once more eliminating any "stray" parameters.

	Lines 51-55, We were just called with DoIt as a parameter, c1 and c2
	are now set up correctly, lets run them.
     1	.KEY c1,c2,c3,c4,c5,c6,c7,c8,c9,ca,cb,FLAG
     2	.  PIPE, an execute file that does pipes!  By: Bruce Barrett. Public Domain
     3	.bra {
     4	.ket }
     5	
     6	if "{FLAG}" eq ""
     7	  execute PIPE "{c1} > RAM:PIPE$$$" "{c2}" "{c3}" "{c4}" "{c5}" "{c6}" "{c7}" "{c8}" "{c9}" "{ca}" "{cb}" "is|?"
     8	  skip END
     9	endif
    10	
    11	if "{FLAG}" eq "is|?"
    12	  if "{c2}" eq ""
    13	    echo "PIPE: Error, no *"|*" (bar) found!"
    14	    skip END
    15	  endif
    16	  if "{c2}" eq "|"
    17	    if "{c4}" EQ ""
    18	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$" "" "" "" "" "" "" "" "" "" "DoIt"
    19	      skip END
    20	    endif
    21	    if "{c5}" EQ ""
    22	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$ {c4}" "" "" "" "" "" "" "" "" "" "DoIt"
    23	      skip END
    24	    endif
    25	    if "{c6}" EQ ""
    26	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$ {c4} {c5}" "" "" "" "" "" "" "" "" "" "DoIt"
    27	      skip END
    28	    endif
    29	    if "{c7}" EQ ""
    30	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$ {c4} {c5} {c6}" "" "" "" "" "" "" "" "" "" "DoIt"
    31	      skip END
    32	    endif
    33	    if "{c8}" EQ ""
    34	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$ {c4} {c5} {c6} {c7}" "" "" "" "" "" "" "" "" "" "DoIt"
    35	      skip END
    36	    endif
    37	    if "{c9}" EQ ""
    38	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$ {c4} {c5} {c6} {c7} {c8}" "" "" "" "" "" "" "" "" "" "DoIt"
    39	      skip END
    40	    endif
    41	    if "{ca}" EQ ""
    42	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$ {c4} {c5} {c6} {c7} {c8} {c9}" "" "" "" "" "" "" "" "" "" "DoIt"
    43	      skip END
    44	    endif
    45	  else
    46	    execute PIPE "{c1} {c2}" "{c3}" "{c4}" "{c5}" "{c6}" "{c7}" "{c8}" "{c9}" "{ca}" "{cb}" "" "is|?"
    47	    SKIP END
    48	  endif
    49	endif
    50	
    51	if "{FLAG}" eq "DoIt"
    52	  {c1}
    53	  {c2}
    54	  delete RAM:PIPE$$$
    55	endif
    56	LAB END

mwm@eris.BERKELEY.EDU (Mike Meyer) (01/21/87)

I remember that posting; I also remember being singularly unimpressed
at the time. You could do similar things on CP/M-80, if you were
tricky and nasty enough.

You see, that's not pipe()s, that's just a shell script to make using
temp files look like the Unix pipe syntax. Sorta like the difference
between writing and typing; it all looks the same, but the content is
different!

For instance, I can add detab a 1Meg file and print the result using
real pipes; that execute script will run out of memory (unless there's
something really nasty I missed; always a possibility!).

The key thing about a pipe is that it's a FIFO queue, with a limited
buffer size. You can pass unlimited amounts of data through one, yet
it will always use a small amount of space. Most OS's have some kind
of facility to do this, so you can do pipes on most OS's.

What made Unix pipes so nifty was that the fifo mechanism was right
out there where the users could get to it. You didn't have to make
half-a-dozen system calls in assembler to set it up, it only took one
character on the command line.

	<mike

news@cit-vax.Caltech.Edu (Usenet netnews) (01/21/87)

Organization : California Institute of Technology
Keywords: 
From: tim@tomcat.Caltech.Edu (Tim Kay)
Path: tomcat!tim

In article <2023@tekgvs.UUCP> keithe@tekgvs.UUCP (Keith Ericson) writes:
>Guess what.  You can use "pipes" on the Amiga to pipe the output of one
>process to the input of another.
>
>4) All of this will work faster if you run it out of RAM:.
>     7	  execute PIPE "{c1} > RAM:PIPE$$$" ...
>    18	      execute PIPE "{c1}" "{c3} < RAM:PIPE$$$" ...
>    54	  delete RAM:PIPE$$$

Even MS-DOS gives you this much.  Under Unix, a pipe is different.  The
source program is automatically blocked when the pipe buffer is full,
and the destination program is allowed to run.  When the pipe buffer is
empty, the destination program is blocked, and the source program is
resumed.  The advantage is that you only need enough memory for the
buffer, not for the entire source program's output.

Somebody made mention of a pipe device.  Does it do effectively what Unix
does?  Or does it just save all the source's output as above?

Timothy L. Kay				tim@csvax.caltech.edu
Department of Computer Science
Caltech, 256-80
Pasadena, CA  91125

joels@tekred.UUCP (01/24/87)

>The key thing about a pipe is that it's a FIFO queue, with a limited
>buffer size. You can pass unlimited amounts of data through one, yet
>it will always use a small amount of space. Most OS's have some kind
>of facility to do this, so you can do pipes on most OS's.

	<mike

The real advantage of pipes over files that imitate them is that all
processes in the chain can run simultaneously. The second process can start
as soon as the pipe buffer has data in it. After the first buffer of
data has passed through the chain, and you are reading the data on the screen
the other processes can keep the display buffer full and ready for
display. This also means that if you only need to look at the beginning
of the data only the beginning needs to be processed. With imitation pipes
the first process must process all of the data and close the file and the
second does the same, etc. All of the preliminary processes must
process all the data even if you only need to see the first line.

Joel Swank
Tektronix, Redmond, Oregon

mwm@eris.UUCP (01/25/87)

In article <946@tekred.UUCP> joels@tekred.UUCP (Joel Swank) writes:
>>The key thing about a pipe is that it's a FIFO queue, with a limited
>>buffer size.
>
>The real advantage of pipes over files that imitate them is that all
>processes in the chain can run simultaneously. 

Which also means that the processes can overlap I/O and processing
with each other, so that the group takes less wall-clock time than it
would if you had to run them sequentially.

Ain't real pipes neat things? Of course, to get this advantage, you
gotta have true multitasking....

	<mike

flaps@utcsri.UUCP (Alan J Rosenthal) (02/03/87)

In article <946@tekred.UUCP> joels@tekred.UUCP writes:
>The real advantage of pipes over files that imitate them is that all
>processes in the chain can run simultaneously. The second process can start
>as soon as the pipe buffer has data in it.

Hopefully this is not just a nitpick: the second process can start before the
buffer has any data in it.  Thus the first and second processes can both do
their initialization at once.  In other words, the second process is blocked
not merely on an empty pipe, but on a read to an empty pipe.

Another advantage of real pipes, by the way, is that you can provide terminal
input to the first process based on the output of the second process; this
allows a kind of interactive front-end in the style of 'bc'.  bc couldn't be
implemented how it is here on a non-multitasking system.
-- 

Alan J Rosenthal

UUCP: {backbone}!seismo!mnetor!utcs!flaps, ubc-vision!utai!utcs!flaps,
      or utzoo!utcs!flaps (among other possibilities)
ARPA: flaps@csri.toronto.edu
CSNET: flaps@toronto
BITNET: flaps at utorgpu

kosma%human-torch@stc.lockheed.com (Monty Kosma) (06/08/90)

   No flames from me. I am all for Unix-like pipes, and use PIP:, as supplied with
   ConMan. CBM's PIPE: device is just to restrictive for me. I don't know when
   they are going to do them, but until then, I heartily recommend PIP:

   -larry

Yeah, and with the arp shell (at least) this works great.  I have a dilemma
now, which is that I'm planning to switch over to SKsh, but from what
I've garnered from the (immense!) docs, I can't do concurrent pipes.  

Steve K, if you're out there, could you explain (briefly) what the limits
are on pipes with SKsh, and whether or not (and if not, why not) SKsh allows
support for the (optional) conman PIP: device?

monty

sean2@stretch.cs.mun.ca (Sean Hogan) (06/09/90)

In article <21408@snow-white.udel.EDU> kosma%human-torch@stc.lockheed.com (Monty Kosma) writes:
>
>   No flames from me. I am all for Unix-like pipes, and use PIP:, as supplied with
>   ConMan. CBM's PIPE: device is just to restrictive for me. I don't know when
>   they are going to do them, but until then, I heartily recommend PIP:
>
>   -larry
>
>Yeah, and with the arp shell (at least) this works great.  I have a dilemma
>now, which is that I'm planning to switch over to SKsh, but from what
>I've garnered from the (immense!) docs, I can't do concurrent pipes.  
>...
>monty

This reminds me of something I've been going to ask for some time (nothing
to do with SKsh, sorry) ... has anybody else noticed when using the ARP shell
and concurrent pipes (with PIP:) that only the last command in the pipeline
can be interrupted?  I'm not necessarily talking about ^C interruption -
if you have a `find' being piped through `more' and hit q to quit the pager,
the find continues to completion in the background (producing no output).
I can reason out this behaviour easily enough; it's just annoying if the
early commands do lots of disk access.

	Sean.
---
Sean Hogan, graduate student           sean2@stretch.cs.mun.ca
Department of Computer Science,        sean2@stretch.mun.edu
Memorial University of Newfoundland    ...!uunet!garfield!sean2

koren@hpfelg.HP.COM (Steve Koren) (06/11/90)

> Yeah, and with the arp shell (at least) this works great.  I have a dilemma
> now, which is that I'm planning to switch over to SKsh, but from what
> I've garnered from the (immense!) docs, I can't do concurrent pipes.  

> Steve K, if you're out there, could you explain (briefly) what the limits
> are on pipes with SKsh, and whether or not (and if not, why not) SKsh allows
> support for the (optional) conman PIP: device?

SKsh in 1.3 and previous used *only* temporary file pipes.  In 1.4 only
temp file pipes were supported but there was the capability to use
one (count 'em!) concurrent pipe at a time using the AmigaDos pipe:
handler.  I ran into an inexplicable problem with using more than one
at once (and no, it wasn't anything you'd probably guess like trying
to use the same name for >1 pipe).  I may switch to pip: instead of
pipe: for 1.5.  However, my system went belly-up pretty severely this
weekend so I am kinda stuck for the moment.   At any rate, it may be
in 1.5 but I can't promise it.

        - steve