69, condensed version: proc1={cmd1 arg arg arg} | {cmd2 arg arg arg} | proc1:0 69, more verbose (traditional) version: proc1={cmd1 arg arg arg} proc2={cmd2 arg arg arg} proc1:1 | proc2:0 proc2:1 | proc1:0 cat: env:0 | env:1 tee that copies everything to "/tmp/foo" as well: stdio:0 | p=[hub] p:* | stdio:1 p:* | [open /tmp/foo] tee that copies everything to "/tmp/foo" as well, condensed: stdio:0 | p=[hub] | stdio:1 p:* | [open /tmp/foo] Some draw script that may use timers and handles stderr, verbose: # use stdio plumblib for linesplit and stdio shorthands include stdio # start all processess ai_i=[hub] | ai={awk -f util.awk -f ai.awk} | $LSP | ai_o=[hub] vis={animator} # set up pipes and filters ai_o:* | [regex pattern="^anim:"] | vis:0 ai_o:* | [regex pattern="^plumb:"] | super:* ai:2 | $LSP | [affix prefix="ai error:"] | err:* vis:2 | $LSP | [affix prefix="animator error:"] | err:* vis:1 | $LSP " [affix prefix="anim:"] | ai_i:* super:1 | [affix prefix="super:"] | ai_i:* Some draw script that may use timers and handles stderr, condensed: # start all processess; super->ai->vis->ai super:1 | [affix prefix "super:"] | ai_i=[hub] | ai={awk -f util.awk -f ai.awk} | $LSP | ai_o=[hub] | [regex pattern="^anim:"] | vis={animator} | $LSP | [affix prefix="anim:"] | ai_i:* # set up extra pipes and filters (ai->super and errors) ai_o:* | [regex pattern="^plumb:"] | super:0 ai:2 | [affix prefix="ai error:"] | $LSP | err=[hub] | env:2 vis:2 | [affix prefix="animator error:"] | $LSP " err:* An alternative to filters is to use multiple input and output FDs: # by UNIX/libc default 0, 1 and 2 are stdin, stdout and stderr, we don't # need to touch them but can create 2 more sinks and 3 more sources # (sink is an input for the process, source is an output from the process) procA={cmd arg arg arg} procB={cmd arg arg arg} # later on we can pipe these fds procA:5 | procB:1 procB:0 | procA:3 (not implemented yet Set up timers and display the result on stdout of plumb: # 0.5 Hz, 5 times t1=[timer period=2 repeat=5] # when ((sec % 5) == 0), 7 times t2=[timer sec %= 5 repeat=7] # when minute is exactly 12, always (repeat to infinity) t3=[timer minute == 12] # relay events super:1 | env:1 # timers are not sticky by default, we need something that lets plumb # run for a while; make a silent sticky timer; when this timer dies, # no sticky processes will be left and plumb will quit even if # other timers (t3) are still running [timer period=45 repeat=1 noevent=1]:sitcky=yes ) Using templates: # this template can be inserted in a pipe to copy each line # prefixed with f1 to a given file_name and make a # copy prefixed with f2 to an internal fd (2) foo=' env:0 | $LSP | h=[hub] | env:1 h:* | [affix prefix="f1"] | [open $file_name] h:* | [affix prefix="f2"] | env:2 ' env:0 | bar=[new foo file_name=file1] | env:1 bar:2 | [open LOG] # it is also possible to reach internal processes of the template # (more precisely the instance of the template); for example # we can tap the tee in bar and do some other prefixing bar.t:* | [affix prefix="f3"] | [open /tmp/hah] # because of prefixing the process names, multiple instances of the # template may exist under different names env:4 | baz=[new foo file_name=file2] | env:5