Pipelines Without Pipes
The pipeline
program constructs a pipeline from its arguments. The first argument is the separator. The program splits the command line on separator arguments and constructs a pipeline from the components.
Here’s what it looks like in use:
What good does this do? If you dynamically assemble a pipeline in a shell program, you must pass it through shell parsing in order to execute it. This brings all of the difficulties of argument quoting into play. The pipeline
construction does this in a safe way. The caller can manipulate the entire pipeline as a set of ordinary arguments without worrying about interpolation problems.
The underlying code looks like this:
pipeline_cmd() {
local prefix="$1"
local sep="$2"
shift 2
local cmd=''
local i=3
local p='${1}'
for a in "$@"
do
if test "$a" = "${sep}"
then
cmd="${cmd} |"
p='${1}'
else
cmd="${cmd} \"${p}\${$i}\""
p=''
fi
i=$((i + 1))
done
printf '%s\n' "${cmd}"
}
# pipeline prefix sep prog1 [sep prog2 ...]
pipeline() {
eval "$(pipeline_cmd "$@")"
}
The pipeline
program calls the pipeline
function with an empty first argument. You can find the code here.