FreeBSD Manual Pages
ORCH(5) File Formats Manual ORCH(5) NAME orch -- orchestration script file format DESCRIPTION The porch(1) program spawns other command-line utilities and drives them via a pts(4), using scripts referred to as orch scripts. SCRIPT FILES orch script files are written in Lua with a limited environment avail- able. Notably, absolutely none of the standard environment is in- cluded. orch scripts are built around constructing match() blocks, sometimes in conjunction with multiplexing one() blocks. match() blocks in the same context are executed in the specified order. When a match is successful, the beginning of the program output buffer is trimmed up to the character just after the successful match. Future match() blocks are left with the trimmed output buffer to match against. The default timeout for a match to succeed is 10 seconds, and may be changed by specifying a timeout parameter in the match configu- ration. The timeout may also be changed globally for future match blocks with the timeout() function described below. match() blocks may also have a callback specified, which itself may contain any number of match() or one() blocks. orch imports only some parts of the Lua standard library for use in the scriptfile, to minimize the chance of being able to conduct actions that are inherently incompatible with the queuing model that scripts are executed with. Currently, only the assert() and type() functions, and the "string" and "table" modules are exposed. The following functions exist for usage within the scriptfile: cfg(cfg) Set configuration for the current process using the cfg table. The specified cfg is merged into the current configuration. Currently, the only recognized configuration items are those described for the write() function. chdir() Change the directory of the program most recently spawned. This must be called after spawn() and before the process is releeased. There is currently no way to persistly chdir(2) for every spawned process. clearenv(local) Clear the environment. If local is truthy, then the environ- ment is only cleared for the most recent spawn(). debug(string) Writes string out to the stderr of orch, with "DEBUG:" prepended and a newline appended to it. This directive is enqueued, not processed immediately unless it is called from within a failure handler. enqueue(function) Add function to the queue to be executed in script order. If enqueue() is used in a context that does not execute the queue, such as from another enqueued callback or from a failure con- text, then it will immediately call the function instead of en- queueing it. eof(timeout) Check for eof from the process. If the process has closed its side because it was killed by signal, then orch will crash with an assertion. If timeout is not specified, the default timeout will be used. This directive is enqueued, not processed immediately. exit(status) Exit with the designed status code. This directive is enqueued, not processed immediately unless it is called from within a failure handler. fail(function) Sets up a failure handler. Pass nil to reset the failure han- dler. The function will receive one argument, the contents of the buffer, to aide in debugging. By default, orch will exit with a status of 1 when a match block fails. The failure han- dler prevents the default exit, but may itself call exit(). The return value is ignored. This directive is enqueued, not processed immediately. The fail() function is not available as a direct child of a one() block. getenv(key) Get the value of key from the current environment. This directive is always processed immediately and may not be used in a queued context. getenv() is expected to mostly be used for debugging purposes. hexdump(string) Writes an hd(1) style hexdump output to stderr of the input string. This directive is always processed immediately, and is intended to be used within a failure context to aide in analysis of why a match failed. log(logfile) Sets a logfile for subsequent input and output to the process. The logfile may be a string specifying a filename or an open file (for lib users). If a filename is specified, then orch will open it in write-append mode and preserve existing con- tents. matcher(type) Changes the default matcher for subsequent match blocks to the type described by type. The default type is the "lua" matcher, which interprets match patterns as lua patterns and executes them accordingly. Note that Lua string processing still ap- plies for every pattern matcher. e.g., "\r" will be inter- preted as a carriage return for these non-default pattern matchers. The following matcher options are available: "lua" Uses Lua pattern matching to match patterns. "plain" Treats the pattern as a plain old string; no characters are special. "posix" Treats the pattern as a POSIX extended regular expres- sion. See re_format(7) for more details. "default" An alias for the "lua" matcher. pipe(commandstr, linefilter) Execute the command in commandstr and pipe any output from it into the spawned process. Note that, unlike other actions that commands, the pipe() action will only take the command as a string or a table that can be coerced into a command string. The result will be passed directly to io.popen(). If a linefilter callback is passed, then every line from the given command will be ran through it and the result of the call written to the process instead. If the callback returns nil, then the line is skipped. raw(boolean) Changes the raw write() state on the process. release() Releases a spawned process for execution. This is done implic- itly when a match() block is first encountered. This directive is enqueued, not processed immediately. setenv(key, value, local), setenv(table, local) Set the environment variable key to value in the environment. If local is truthy, then the value is only set for the most re- cent spawn(). The table variant may be used to set multiple environment variables at once. size(width, height) Set or get the size of the terminal associated with the process. If at least one of width or height are not nil, then size() will resize that dimension of the window. The new cur- rent size of the window is always returned. The window will start off on a fresh spawn with a width and height of 0. The size of the window is never persisted across processes. This directive is always processed immediately, and thus should always be used in either an enqueue() or fail context. sleep(duration) Sleeps for at least the specified duration, in seconds. Frac- tional seconds are supported. As implemented, orch may delay execution for a little longer than the specified duration, but not for any less time. This directive is enqueued, not processed immediately unless it is called from within a failure handler. spawn(...) Spawns a new process. The arguments to spawn() are in the tra- ditional argv style. They may either be specified directly as arguments to the function, or they may instead be constructed as a single table. orch will execute a standard PATH search via execvp(3). Note that the script's directory is added to PATH before execution begins. The spawned process will inherit the running environment. If the process cannot be spawned, then orch will exit. Note that only one process at a time may be matched against. If a new process is spawned, then the previous process will be killed and subsequent matches will be against the new process. This directive is enqueued, not processed immediately. stty(field, set, unset) Change the specified field as described by set and unset. field should be one of "cflag", "iflag", "lflag", "oflag", or "cc", corresponding to the similarly named fields in termios(4). For the flag fields, the bits in set will be set in the new mask, and the bits in unset will be unset in the new mask. Either may be 0 or nil to indicate no bits to be set or unset respectively. The masks for each field may be found in the "tty" table in the script's global environment. For in- stance, ICANON's mask may be referenced as "tty.lflag.ICANON". For "cc", the unset argument is ignored, and set should be a table whose keys correspond to a defined "V*" constant, and whose values are either the empty string to indicate that the field should be disabled, an integer for VMIN and VTIME, or a string of the form "^X" to indicate ctrl-X. Supported entries may be found in the "tty" table in the script's global environment. The "tty.cc" table's keys corre- spond to supported characters, e.g., "tty.cc.VEOF", and the as- sociated values are all truthy to indicate that they are sup- ported. This directive is enqueued, not processed immediately. timeout(val) Adjust the default timeout to val seconds for subsequent match() blocks. The default timeout at script start is 10 sec- onds. This directive is processed immediately. write(str, cfg) Write str to stdin of the spawned process. If the process is in raw() mode, then write() will write the entire str() out as given. If the process is not in raw() mode, which is the de- fault, then escape sequences and control characters will be processed. Note that lua strings are naturally escape- processed in addition to any escaping done by orch. For exam- ple, if one wants to send a literal "^D" in non-raw mode, then "\\^D" is the correct sequence to do so. The first backslash escapes the second backslash, then orch sees just a single backslash preceding the circumflex. This directive is enqueued, not processed immediately. Execu- tion does not continue to the next command until the str has been completely written. The cfg argument is a table of configuration items for the cur- rent send. The following elements are supported: rate The rate at which to send str. This is specified as a table with, at a minimum, a bytes item to describe how many bytes to send in a single batch. orch also ac- cepts a delay item to describe how long to wait in be- tween each batch, in seconds. As with the sleep() function, fractional seconds are supported. With a delay of 0, orch will still call into sleep() with no delay. With no delay, orch will send each batch with no delay in between them. BLOCK PRIMITIVES Match Blocks The "match" blocks are the core primitive of orch scripts. Setting them up sounds complicated, but some Lua-supplied sugar actually makes construction of match() blocks relatively elegant. More on this will be demonstrated in the "EXAMPLES" section. The match() function takes exactly one argument: a pattern to match against. These patterns are Lua patterns, used without modification to check the output buffer. The match() returns an anonymous function that may be called again with a table to describe the properties of the match() block. The following properties are available: callback Specifies a function to call if the match succeeds. The callback function may itself construct additional "match /" "any" blocks, that will then be used for output matching before proceeding after the successfully matched match() block. timeout Overrides the current global timeout. The timeout value is measured in seconds. One Blocks Constructing a "one" block is as simple as calling one(). The one() function takes a callback as its argument, and this function should setup two or more match() blocks to multiplex between. The first matching pattern, as specified in script order, will be used and the rest of the block discarded. The usual rules of match() blocks apply at this point; the callback will be executed, and the callback may also do further matching. Note that timeout likely does work in a one() block as you might ex- pect. orch will effectively wait the full length of the longest time- out for any of the match() blocks that it contains. If some blocks have shorter timeouts than others, then orch will timeout after the shortest timeout it sees in the block at the time. If the shorter timeout block still does not match, it will be removed from considera- tion and we will wait up until the next shortest timeout would have ex- pired. That is, a match will not be granted if the matching output comes in after the timeout would have elapsed, even if we are still waiting on input for other blocks. EXAMPLES This listing demonstrates the basic features: -- Literally spawns a new command: "Hello there", that we will be examining. spawn("echo", "Hello there") -- Sets a new default for subsequent match blocks timeout(3) -- Just matches the initial "Hello", output buffer now contains " there" to -- match against. match "Hello" -- You are also welcome to do this, if it feels more natural to you: match("t") -- This is effectively ignored since the only match block after it specifies an -- explicit timeout. If we had another match block after that one, though, then -- it would use a one second timeout by default. timeout(1) -- This one will fail to match, but we have configured a higher timeout than the -- global timeout we configured above (one second). match "Friend" { timeout = 5, } This block demonstrates bidirectional communication: spawn("cat") -- The tty we setup is in canonical mode by default, so the trailing \r is -- necessary for the spawned process to read it (unless the process turns off -- canonical mode). write "Hello there\r" match "Hello" { callback = function() debug("Hello matched") end } This block demonstrates more complex nested match blocks: spawn("cat") write "Hello world\r" match "Hello" { callback = function() -- This will match the world sent above... match "world" { callback = function() -- ... and additionally write "FRIENDS" out write "FRIENDS\r" end } end } match "FRIENDS" { callback = function() debug "FRIENDS seen!" end } This block demonstrates one blocks: spawn("cat") write "One\r" -- These might feel a little bit awkward one(function() -- This match block will end up used because it is specified first. match "ne" { callback = function() debug("This one will be called.") -- Script execution continues after the one() block that contains -- this match. write "One\r" end } -- This match block will effectively be thrown away. match "One" { callback = function() debug("This one will not be called") end } end) -- This one will match, because the "ne" block's callback wrote it out. match "One" More examples can be found in /usr/share/porch/examples. SEE ALSO porch(1), pts(4), termios(4) FreeBSD Ports 14.quarterly December 6, 2024 ORCH(5)
NAME | DESCRIPTION | SCRIPT FILES | BLOCK PRIMITIVES | EXAMPLES | SEE ALSO
Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=orch&sektion=5&manpath=FreeBSD+Ports+14.3.quarterly>