Runs an external command.
<p:declare-step type="p:os-exec"> <input port="source" primary="true" content-types="any" sequence="true"/> <output port="result" primary="true" content-types="any" sequence="true"/> <output port="error" primary="false" content-types="any" sequence="true"/> <output port="exit-status" primary="false" content-types="application/xml" sequence="false"/> <option name="command" as="xs:string" required="true"/> <option name="args" as="xs:string*" required="false" select="()"/> <option name="cwd" as="xs:string?" required="false" select="()"/> <option name="error-content-type" as="xs:string" required="false" select="'text/plain'"/> <option name="failure-threshold" as="xs:integer?" required="false" select="()"/> <option name="path-separator" as="xs:string?" required="false" select="()"/> <option name="result-content-type" as="xs:string" required="false" select="'text/plain'"/> <option name="serialization" as="map(xs:QName,item()*)?" required="false" select="()"/> </p:declare-step>
The p:os-exec
step runs the external command as specified in the command
and args
options. It passes the
input that arrives on its source
port as standard input to the command. The standard output and standard error of the command are
returned on the result
and error
ports.
Ports:
Port | Type | Primary? | Content types | Seq? | Description |
---|---|---|---|---|---|
|
|
|
|
| The document that appears on the standard input of the external command. If the This document is serialized (as if written to disk) first. For this, the value of the The port accepts zero or one document. For multiple documents, error If you want the source port to be empty, you must specify this: <p:with-input port="source"> <p:empty/> </p:with-input> |
|
|
|
|
| The result of the external command: what was written by the command on the standard output. The standard output of the command is processed as if it was read from disk by If there is no content on the standard output, this port will be empty. |
|
|
|
|
| The error result of the external command: what was written by the command on the standard error. The standard error of the command is processed as if it was read from disk by If there is no content on the standard error, this port will be empty. |
|
|
|
|
| A |
Options:
The p:os-exec
step can be used to run an external command. For instance, a Python script or post-process some result with something not
available in XProc.
The command itself is specified using the command
and args
options. Every string in the
args
option is a separate argument (also when it contains spaces). What appears on the result> port is passed as the
command’s standard input.
The command’s output and error information is returned on the result
and error
ports. You can use the
result-content-type
and error-content-type
options to tailor how this comes out.
This example runs the (Windows) dir
command (that shows a directory overview) on the data/
subdirectory of where
the pipeline is stored. It does so by starting the Windows command processor (called cmd
) with the arguments
/C dir data
. This is the same as typing dir data
on the Windows command line.
A problem we have here is that we need to set the current working directory (in the cwd
) to the location of the pipeline.
The example computes this, based on the static-base-uri()
of the pipeline, using regular expression magic. The cwd
option of p:os-exec
does not accept a URI, so we have to strip the file:/
in front also. The result is stored in the
$cwd
variable.
Pipeline document:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0"> <p:output port="result"/> <p:variable name="cwd" select="static-base-uri() => replace('^file:/+', '') => replace('[^/\\]+$', '')"/> <p:os-exec command="cmd" cwd="{$cwd}"> <p:with-option name="args" select="('/C', 'dir', 'data')"/> <p:with-input port="source"> <p:empty/> </p:with-input> </p:os-exec> </p:declare-step>
Result document (text):
Volume in drive C is OS Volume Serial Number is 9EA2-E853 Directory of C:\…\data 08/01/2025 10:44 <DIR> . 08/01/2025 10:44 <DIR> .. 08/01/2025 10:44 44 x1.xml 08/01/2025 10:44 44 x2.xml 2 File(s) 88 bytes 2 Dir(s) 518.830.137.344 bytes free
The documents appearing on the output ports only have a content-type
property. They have no other document-properties
(also no base-uri
).
Error code | Description |
---|---|
It is a dynamic error if more than one document appears on the | |
It is a dynamic error if the command cannot be run. | |
It is a dynamic error if the current working directory cannot be changed to the value of the | |
It is a dynamic error if the | |
It is a dynamic error if the exit code from the command is greater than the specified |
This description of the p:os-exec
step is for XProc version: 3.0. This is a non-required step (an XProc 3.0 processor does not have to support this).
The formal specification for the p:os-exec
step can be found here.
The p:os-exec
step is part of categories:
The p:os-exec
step is also present in version:
3.1.