# $EPIC: exec_function.txt,v 1.4 2006/08/29 18:22:56 sthalik Exp $
$exec(<program> <args>)
This function offers an easier interface and a finer grain control over the process than /exec, but comes at the expense of being more dangerous to use.
You could use this function to implement real time text filtering or scrambling using the unix tool “sed” perhaps.
$exec() might be a better alternative to $perl() and $tcl() for people who wish to distribute their scripts and need a certain level of compatibility that the embedded languages don't provide.
One writable FD and two readable FDs.
#
# An example of what we can expect.
#
fe ($exec(tr a-zA-Z A-Za-z)) fd {
echo $write($fd qwerASDF):$read($fd):$close($fd)
}
#
# Output
#
Out1: 9::0 # STDIN wrote 9 bytes (including NL), read failed,
Out2: -1:QWERasdf:0 # STDOUT write failed, read 9 bytes,
Out3: -1::0 # STDERR write failed, read nothing,
# FD close succeeded in all cases.
#
# Fortunately for us, md5sums i/o is very predictable. It, like
# some other programs uses the EOF of its input as a signal to start
# delivering output, so it is always safe for $exec() so long as we
# do not attempt to read its output before closing its input.
#
# Note that the technique we use here can be used for most programs
# and all filters if we restrain ourselves from writing too much data
# to STDIN. Exactly how much data can be written depends on the "pipe
# size" ulimit which can be changed with the ulimit command in any(?)
# bourne compatible shell.
#
# Also note that in these examples, the FDs that aren't used are
# closed before processing begins rather than after. It is
# important to do this because if the program tries to read/write
# a closed FD, it will always return immediately rather than
# blocking.
alias md5 {
# a fast way to set three local variables.
fe ($exec(md5sum)) in out err {break}
@ close($err)
@ write($in $*)
@ close($in)
@ function_return = read($out)
@ close($out)
}
#
# Translate upper to lower and lower to upper using a perl script.
# The critical thing about this alias is the $|=1 in the perl script,
# which turns autoflush on so that we receive the output immediately
# after feeding it the input. The gnu tr command cannot be made to
# do this, which makes it unsuitable for this application.
#
# Anyway, the reason this is critical is that we're going to $exec()
# the perl script outside of the alias, perhaps at bootup, and leave
# it running in the background forever with the assumption that every
# line we give it is going to give us precisely one line back. Of
# course, this is a very delicate thing since errors are going to
# accumulate.
#
# Also, note the double quotes where we might normally use single
# quotes in the shell. The input is broken into arguments according
# to epics "word" rules. There is no equivalent to the single quotes
# under these rules, though you can escape "quoting hell" by wrapping
# the relevant parts of your script in braces like I have for this
# example.
#
fe ($exec(perl -lpe "BEGIN{$|=1};{tr/a-zA-Z/A-Za-z/}")) in out err {
@ ::transcase.in = in
@ ::transcase.out = out
@ close($err)
break
}
alias transcase {
@ write($transcase.in $*)
return $read($transcase.out)
}