How to Pipe Script Output and Logs into systemd Journal in Ubuntu Using systemd-cat

In modern Linux administration, shell scripts, cron jobs, database backups, and custom automation daemons generate vital operational telemetry. Historically, administrators redirected script output to unstructured flat log files located in /var/log/ using standard shell redirection (such as >> /var/log/backup.log 2>&1). However, managing flat log files requires implementing manual log rotation rules (via logrotate), parsing unindexed timestamps with grep or awk, and managing disk fill risks when logs expand uncontrollably.

Under Ubuntu distributions governed by systemd, the central logging infrastructure is managed by systemd-journald. To allow standard shell pipelines, interactive terminal commands, and legacy cron jobs to write directly into the structured systemd journal without writing dedicated systemd service units, systemd provides systemd-cat. By routing standard input and output through systemd-cat, administrators can tag log streams with custom syslog identifiers, assign exact priority levels (from debug to emergency), and query aggregated logs seamlessly using journalctl.

Architecture of systemd-cat and journald Socket Redirection

The systemd-cat utility functions as an I/O pipeline bridge between standard Unix process file descriptors and the systemd journal logging engine:

  • Socket Transport: When invoked, systemd-cat opens a direct stream connection to the /run/systemd/journal/stdout UNIX domain socket exposed by systemd-journald.
  • Structured Metadata Injection: Lines read from standard input are packaged into native journal entries enriched with contextual metadata: process identifier (PID), user UID/GID, monotonic boot timestamp, wall-clock time, custom syslog tag (identifier), and priority level.
  • Indexing and Compression: Incoming log entries are automatically indexed, binary-encoded, and compressed inside journal files (/var/log/journal/), enabling rapid filtering across millions of records.
  • Execution Wrapper: In addition to piping standard input, systemd-cat can directly execute child binaries or shell commands, capturing both stdout and stderr transparently.

Piping Command and Pipeline Output into the Journal

The simplest way to use systemd-cat is by piping the standard output of any command or script directly into its input stream.

To pipe the output of an arbitrary command (such as a directory size calculation) into the journal with a custom identifier:

du -sh /var/www | systemd-cat --identifier="disk-audit"

You can verify that the message was accepted by querying the journal using journalctl with the -t (identifier) flag:

journalctl -t disk-audit --no-pager

The output displays the formatted entry:

Nov 08 05:45:12 ubuntu-server disk-audit[10425]: 14G  /var/www

Executing Commands Directly as Child Processes

Rather than relying on shell pipe syntax—which by default only captures stdout unless redirected—you can invoke commands directly through systemd-cat. This automatically captures both standard output and standard error simultaneously.

To execute a Python backup worker as a child process under systemd-cat:

systemd-cat --identifier="db-migration" --priority="info" python3 /opt/scripts/migrate_records.py

If the Python script prints informational messages to stdout and runtime tracebacks to stderr, both streams are captured, timestamped, and stored under the db-migration journal tag.

Assigning Syslog Priorities and Facilities

Systemd journal supports standard RFC 5424 syslog priority levels, ranging from emerg (priority 0) to debug (priority 7). Assigning accurate priorities enables efficient log filtering during incident analysis.

The supported priority names and corresponding integer values include:

  • emerg (0): System is unusable.
  • alert (1): Action must be taken immediately.
  • crit (2): Critical conditions.
  • err (3): Error conditions.
  • warning (4): Warning conditions.
  • notice (5): Normal but significant conditions.
  • info (6): Informational messages.
  • debug (7): Debug-level messages.

To log a critical error alert from a disk monitoring script:

echo "Disk capacity exceeded 95% on /data volume" | systemd-cat -t "storage-monitor" -p "crit"

To query only high-severity entries (warnings, errors, and critical alerts) logged by this script:

journalctl -t storage-monitor -p warning..crit

Integrating systemd-cat Inside Shell Scripts

To route all output from an entire Bash automation script directly into the systemd journal without appending systemd-cat to every individual command, redirect the script’s primary file descriptors within the script header using exec.

Create a backup maintenance script:

sudo nano /usr/local/bin/nightly_sync.sh

Populate the script with automated journal redirection:

#!/bin/bash
# Automatically redirect all stdout and stderr from this script to systemd-journald
exec 1> >(systemd-cat -t "nightly-sync" -p "info")
exec 2> >(systemd-cat -t "nightly-sync" -p "err")

echo "Starting nightly rsync synchronization..."
rsync -avz /data/ /mnt/backup/data/

if [ $? -eq 0 ]; then
    echo "Rsync synchronization completed successfully."
else
    echo "Rsync failed with non-zero exit status!" >&2
    exit 1
fi

Make the script executable:

sudo chmod +x /usr/local/bin/nightly_sync.sh

When this script runs (manually, via cron, or via cloud-init), normal messages are categorized as info, while failure messages printed to standard error are automatically catalogued with err priority in the systemd journal.

Querying and Exporting Journal Entries via journalctl

Once logs are routed through systemd-cat, leverage the full query power of journalctl:

To view logs generated by a specific identifier since the last system boot:

journalctl -b -t nightly-sync

To view logs generated within a specific timeframe (e.g. the last 2 hours):

journalctl -t nightly-sync --since "2 hours ago"

To output structured JSON-formatted records for ingestion into central SIEM or Elasticsearch collectors:

journalctl -t nightly-sync -o json-pretty -n 5

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.