Command-line client
recado pub publishes a message, recado sub prints messages until interrupted. Both work with any MQTT broker.
To administer a broker, use mercurioctl.
Publishing
# A message, at QoS 1 recado pub -t sensors/kitchen -m 21.5 -q 1 # From standard input echo '{"temp": 21.5}' | recado pub -t sensors/kitchen --content-type application/json # Each new log line as a message tail -F /var/log/app.log | recado pub -t logs/app -l # A binary file, such as an image or a firmware image recado pub -t cameras/door/snapshot -f snapshot.jpg # Retained, so new subscribers get it at once recado pub -t status/door -m open -r # An MQTT 5 request, with properties recado pub -t requests/lamp -m on --response-topic replies/me \ --correlation-data 42 --user-property source=cli --message-expiry 60
| Option | Meaning |
|---|---|
-t, --topic | Topic to publish to (required) |
-m, --message | Payload, as text. Without it or -f, standard input is published byte for byte |
-f, --file PATH | Publish the contents of a file, binary or not |
-l, --line | Publish each line of standard input as its own message as it comes, on one connection. The line feed, and a carriage return before it, are left out; empty lines are skipped |
-q, --qos | 0, 1 or 2 (default 0) |
-r, --retain | Retain the message on the broker |
--content-type | Content type of the payload, such as a MIME type |
--response-topic | Topic a reply should be published to |
--correlation-data | Data that ties a reply to its request, as text |
--correlation-data-hex | The same as bytes, in hex, such as 00ff7a |
--message-expiry | Seconds the broker keeps the message for subscribers yet to get it |
--utf8 | Mark the payload as UTF-8 text |
--user-property key=value | User property; may be repeated |
--will-topic and the other will options | As for sub, below; useful with -l, which keeps the connection open |
Subscribing
# Print payloads, with their topics recado sub -t 'sensors/#' -T # Several filters recado sub -t 'sensors/#' -t 'alerts/#' -T # In a script: the device's retained status, or status 4 after 10 s recado sub -t devices/7/status -C 1 -W 10 # A persistent subscriber that survives broker restarts and network loss recado sub -t 'alerts/#' -i monitor -c -x 3600 --reconnect 5 -q 1 # With a will, published if the subscriber disappears recado sub -t 'cmd/#' --will-topic status/monitor --will-message offline --will-retain
| Option | Meaning |
|---|---|
-t, --topic | Topic filter; may be repeated (required) |
-q, --qos | QoS of the subscriptions (default 0) |
-T, --print-topic | Print the topic and : before each message |
--format text|json | text prints each payload byte for byte, then a line feed; json prints one JSON object per line (below) |
--no-local | Don't receive messages this client publishes itself |
--retain-as-published | Keep the retain flag messages were published with |
--retain-handling | Retained messages on subscribing: 0 always, 1 only for new subscriptions, 2 never |
--subscription-id | Identifier the broker attaches to messages matching these subscriptions |
-C, --count N | Exit after N messages, retained ones included |
-W, --timeout SECONDS | As mosquitto_sub's -W: exit with status 4 if still running this long after connecting. With -C, that means fewer than N messages came; without it, sub always ends this way |
--reconnect SECONDS | Reconnect after losing the connection, waiting this long between attempts |
--will-topic, --will-message | Will published by the broker if the client disconnects unexpectedly |
--will-qos, --will-retain, --will-delay | QoS, retain flag and delay (MQTT 5) of the will |
JSON lines
With --format json, each message is one line holding a JSON object:
$ recado sub -t 'sensors/#' --format json
{"payload":"21.5","payload_base64":"MjEuNQ==","qos":0,"retain":false,"topic":"sensors/kitchen"}
| Field | Holds |
|---|---|
topic, qos, retain | Always there |
payload_base64 | The payload in base64; always there |
payload | The payload as text, only when it is valid UTF-8 |
content_type, response_topic, message_expiry, payload_is_utf8 | The MQTT 5 properties of the same name, when the message has them |
correlation_data_base64 | The correlation data in base64, when there is some |
user_properties | [name, value] pairs in the order they came, when there are some; a name may repeat |
subscription_ids | The identifiers of the matching subscriptions that have one |
# The payloads of binary messages, decoded
recado sub -t 'cameras/#' --format json | jq -r .payload_base64 | base64 -d
Connection options
Both commands take these:
| Option | Meaning | Default |
|---|---|---|
-H, --host | Broker host name | localhost |
-p, --port | Broker port | 1883 |
--unix PATH | Connect through this Unix socket instead of TCP; not with -H, -p or the TLS options | |
-i, --client-id | Client id. Left out, it is empty and the broker assigns one; MQTT 3.1 takes no empty id, so there recado sends a random recado- id | assigned by the broker |
-u, --username, -P, --password | Credentials. The password can also come from RECADO_PASSWORD, which other users can't see in ps; -u alone asks for it when standard error is a terminal | |
--auth-method scram-sha-256 | Log in with SCRAM-SHA-256 instead of sending the user name and password in CONNECT: the password, from the same sources, never reaches the broker, and the broker must prove it knows it. Needs -u and MQTT 5 | |
--auth-method scram-sha-256-plus | As scram-sha-256, and bind the login to the TLS connection (SCRAM-SHA-256-PLUS). Needs TLS 1.3 to a broker that terminates it; it fails before CONNECT is sent otherwise, with "channel binding needs a TLS 1.3 connection" | |
-k, --keep-alive | Keep-alive, in seconds | 60 |
-c, --no-clean-start | Keep the session after disconnecting. Needs -i, as with mosquitto: a session kept under an id nobody knows could never be resumed | |
-x, --session-expiry | Seconds the broker keeps the session after the connection closes (MQTT 5) | 0 |
-V, --protocol-version | 5, 311 or 31; also 3.1.1, 3.1 and mosquitto's mqttv5, mqttv311, mqttv31. Anything else is an error | 5 |
--tls | Connect with TLS, verifying the broker with the operating system's certificate store (on Linux the system CA bundle, such as /etc/ssl/certs; the Keychain on macOS; the certificate store on Windows), or, when that holds no usable certificate, the Mozilla roots bundled with the client | |
--cafile | CA certificates (PEM) to verify the broker with, the only ones then trusted; implies --tls | the operating system's store |
--insecure | Skip certificate verification, for testing only; implies --tls | |
--cert PATH, --key PATH | Client certificate and its private key, both PEM, for brokers that authenticate clients by certificate; each needs the other, and they imply --tls | |
--ws, --ws-path PATH | Speak MQTT over a WebSocket on the host and port, wss:// with the TLS options, at this path; not with --unix | /mqtt |
-v, --verbose | Verbose output |
# Over TLS, as alice; asks for the password recado sub -H broker.example.com -p 8883 --cafile ca.crt -u alice -t '#' # In a script, with the password out of ps RECADO_PASSWORD="$(cat ~/.mqtt-password)" recado pub -u alice -t status -m up # Without the password crossing the network recado pub --auth-method scram-sha-256 -u alice -t status -m up # MQTT 3.1.1 recado pub -V 311 -t test -m hello # Through a Unix socket listener recado sub --unix /run/mercurio/mqtt.sock -t 'sensors/#' -T
Shell completions
recado completions <shell> prints a completion script for bash, zsh, fish, elvish or powershell:
recado completions bash > ~/.local/share/bash-completion/completions/recado
recado completions zsh > "${fpath[1]}/_recado"
Exit status
recado uses the exit statuses of mercurioctl, and 4 for sub -W:
| Status | Means |
|---|---|
0 | Success, or sub stopped by Ctrl-C, SIGTERM or its reader going away. On Ctrl-C and SIGTERM it disconnects cleanly, so the broker drops its will |
1 | The broker refused a subscription, or a QoS 1 or 2 message; the message names the filter and the reason |
2 | The broker couldn't be reached, refused the login, or closed the connection; with --reconnect, when the broker refuses the reconnection for good, as for bad credentials or a ban, and the message says why |
3 | Wrong usage, such as an unknown option or a QoS above 2 |
4 | sub -W ran out of time, such as before -C's messages all arrived |
Messages and logs go to standard error, so standard output carries only the payloads.