APIs & Integrations

Host Script Execution

Structr can execute shell scripts on the host system, allowing your application to interact with the operating system, run external tools, and integrate with other software on the server. This opens up possibilities like generating documents with external converters, running maintenance tasks from a web interface, querying system metadata, controlling Docker containers, or integrating with legacy systems.

For security reasons, scripts must be explicitly registered in the configuration file before they can be executed. You cannot run arbitrary commands, only scripts that an administrator has approved.

Registering Scripts

Scripts are registered in structr.conf using a key-value format:

my.pdf.generator = generate-pdf.sh
backup.database = db-backup.sh
docker.restart.app = restart-container.sh

The key (left side) is what you use in your code to call the script. The value (right side) is the filename of the script. Keys must be lowercase.

The Scripts Folder

All scripts must be placed in the scripts folder within your Structr installation directory. The location is controlled by the scripts.path setting, which defaults to scripts relative to base.path.

Scripts must be executable:

chmod +x scripts/generate-pdf.sh

For security, Structr does not follow symbolic links and does not allow directory traversal (paths containing ..). These restrictions can be disabled via configuration settings, but this is not recommended.

Executing Scripts

Structr provides two functions for script execution: exec() for text output and execBinary() for binary data.

exec()

The exec() function runs a script and returns its text output.

StructrScript:

${exec('my.pdf.generator')}
${exec('my.script', merge('param1', 'param2'))}

JavaScript:

$.exec('my.pdf.generator');
$.exec('my.script', ['param1', 'param2']);

Parameters are passed to the script as command-line arguments. They are automatically quoted to handle spaces and special characters.

execBinary()

The execBinary() function runs a script and streams its binary output directly to a file or HTTP response. This is essential when working with binary data like images, PDFs, or other generated files.

StructrScript:

${execBinary(response, 'my.pdf.generator')}
${execBinary(myFile, 'convert.image', merge('input.png'))}

JavaScript:

$.execBinary($.response, 'my.pdf.generator');
$.execBinary(myFile, 'convert.image', ['input.png']);

When streaming to an HTTP response, ensure the page has the correct content type set and the pageCreatesRawData flag enabled.

Parameter Masking

When passing sensitive values like passwords or API keys, you can mask them in the log output:

JavaScript:

$.exec('my.script', [
    'username',
    { value: 'SECRET_API_KEY', mask: true }
]);

The masked parameter appears as *** in the log while the actual value is passed to the script.

Log Behavior

You can control how script execution is logged by passing a third parameter:

Value Behavior
0 Do not log the command line
1 Log only the script path
2 Log script path and parameters (with masking applied)

The default is controlled by the log.scriptprocess.commandline setting.

Security Considerations

Host script execution is a powerful feature that requires careful handling.

Best Practices

Example for Base64 encoding:

// Encode parameters
$.exec('my.script', [$.base64_encode(complexInput)]);

// Decode output
let result = $.base64_decode($.exec('my.script'));
let data = $.from_json(result);

Related Topics