exec and system
Both run a child process with its stdin and stdout wired to the relay. They differ only in how the command line is interpreted.
exec - subprocesses
Runs a program with its stdin and stdout wired to the relay. The target is split on whitespace and passed directly to the program. This is not a shell, so no globbing, quoting, or metacharacters. The child’s stderr is inherited, so its diagnostics go to your terminal rather than into the relayed data.
$ tocat tcp-listen:9000,fork "exec:/usr/bin/env cat"
system - shell commands
Runs the given string through $SHELL -c (or sh -c when SHELL is unset), so
pipes, redirection, globbing, and variable expansion all work. Anything the
string contains runs with tocat’s privileges. Don’t use system with a command
built from untrusted input, or in a config file others can write.
$ tocat tcp-listen:9000,fork "system:grep -v DEBUG | sort -u"
Both
| Option | Description |
|---|---|
name=TEXT | Accepted, but the label stays EXEC(argv) or SYSTEM(command): the command line is the identity |
Both also take the
resilience options,
since a child that fails to spawn can be spawned again. What they cannot do is
give a respawned child the state the last one had: reconnect=keep preserves
plugin state, not the process’s. A respawned cat is fine; a respawned stateful
filter starts over mid-stream.
The child is killed when the relay drops the connection, and is reaped in the
background: the relay ends when the pipes close rather than when the process
does, and a non-zero exit is logged as a warning. That is the opposite of the
process plugin, where a bad exit fails the direction,
because there the child’s output is mid-pipeline and being wrong matters.
The pipes to and from the child are enlarged to match the copy buffer where the platform allows it, see Buffers.
To put a filter between the endpoints rather than at one end, use
process, which has the same two ways of naming a
child and adds control over its stderr.
For a child that needs a terminal rather than a pair of pipes, use
pty-exec. Anything interactive wants it, and so does anything whose
output never appears until it exits, which is libc block-buffering a pipe.