Of course! Here’s a comprehensive guide on how to use the mosquitto_sub command-line tool with Python, covering the most common scenarios.

There are two main ways to approach this:
- Method 1: Using Python as a Client (Recommended): You use a Python MQTT library like
paho-mqttto act as a subscriber directly. This is the most common, flexible, and powerful method. - Method 2: Calling the
mosquitto_subCommand from Python: You use Python'ssubprocessmodule to run themosquitto_subcommand-line tool and capture its output. This is useful if you need to leverage a specific feature of the command-line tool or prefer not to install a library.
Method 1: Using Python as a Client with paho-mqtt (Recommended)
This is the standard way to interact with an MQTT broker from Python. You'll write a Python script that connects to the broker and subscribes to topics.
Step 1: Install the Library
First, you need to install the Paho MQTT client library. Open your terminal or command prompt and run:
pip install paho-mqtt
Step 2: Write the Python Subscriber Script
Here is a basic, well-commented Python script that subscribes to a single topic.

# subscriber.py
import paho.mqtt.client as mqtt
import time
# --- Configuration ---
BROKER_ADDRESS = "test.mosquitto.org" # Public test broker
PORT = 1883
TOPIC = "my_home/temperature" # The topic to subscribe to
QOS = 1 # Quality of Service level
# --- Callback Functions ---
# This function is called when the client successfully connects to the broker.
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Successfully connected to broker!")
# Subscribe to the topic after connecting
client.subscribe(TOPIC, qos=QOS)
print(f"Subscribed to topic: '{TOPIC}' with QoS {QOS}")
else:
print(f"Failed to connect, return code {rc}\n")
# This function is called when a message is received from the broker.
def on_message(client, userdata, msg):
# The msg object contains topic, payload, and qos
print(f"Received message from '{msg.topic}':")
# The payload is in bytes, so we need to decode it (e.g., to UTF-8)
print(f"Payload: {msg.payload.decode('utf-8')}")
print("-" * 20)
# --- Main Script Logic ---
# 1. Create a new MQTT client instance
client = mqtt.Client("python_subscriber_1")
# 2. Assign the callback functions
client.on_connect = on_connect
client.on_message = on_message
# 3. Connect to the broker
print(f"Connecting to {BROKER_ADDRESS}...")
try:
client.connect(BROKER_ADDRESS, PORT, 60)
except ConnectionRefusedError:
print("Connection refused. Is the broker running?")
exit()
# 4. Start a background thread to handle network traffic and callbacks
# This is non-blocking, so your script can continue to run.
client.loop_start()
# 5. Keep the script running to receive messages
try:
while True:
time.sleep(1) # Do other things here
except KeyboardInterrupt:
print("Unsubscribing and disconnecting...")
client.unsubscribe(TOPIC)
client.loop_stop() # Stop the network loop
client.disconnect()
print("Disconnected.")
Step 3: Run the Script
Save the code as subscriber.py and run it from your terminal:
python subscriber.py
You will see:
Connecting to test.mosquitto.org...
Successfully connected to broker!
Subscribed to topic: 'my_home/temperature' with QoS 1
The script will now wait for messages. To test it, you need a publisher. You can use another Python script or the mosquitto_pub command-line tool.
Test with mosquitto_pub:
Open a new terminal and run this command a few times to send messages:

mosquitto_pub -h test.mosquitto.org -p 1883 -t "my_home/temperature" -m "It's 22 degrees Celsius" mosquitto_pub -h test.mosquitto.org -p 1883 -t "my_home/temperature" -m "It's 23 degrees Celsius"
You will see the output in your subscriber.py terminal:
Received message from 'my_home/temperature':
Payload: It's 22 degrees Celsius
--------------------
Received message from 'my_home/temperature':
Payload: It's 23 degrees Celsius
--------------------
Method 2: Calling mosquitto_sub from Python with subprocess
This method runs the mosquitto_sub command as a separate process and reads its output. This is less efficient for continuous message streams but can be useful for simple, one-off tasks.
Step 1: Ensure mosquitto-clients is Installed
You need the mosquitto_sub executable on your system.
- On Debian/Ubuntu:
sudo apt-get update sudo apt-get install mosquitto-clients
- On macOS (using Homebrew):
brew install mosquitto
- On Windows: Download the installer from the Mosquitto download page and make sure the
mosquitto_sub.exeis in your system's PATH.
Step 2: Write the Python Script to Call the Command
This script will construct the command and run it.
# call_subscriber.py
import subprocess
import time
# --- Configuration ---
BROKER_ADDRESS = "test.mosquitto.org"
PORT = 1883
TOPIC = "my_home/humidity"
USERNAME = None # Optional: if your broker requires authentication
PASSWORD = None # Optional: if your broker requires authentication
# --- Construct the command ---
# The command is a list of strings, which is safer than a single string
command = [
"mosquitto_sub",
"-h", BROKER_ADDRESS,
"-p", str(PORT),
"-t", TOPIC
]
# Add username and password if they are provided
if USERNAME and PASSWORD:
command.extend(["-u", USERNAME, "-P", PASSWORD])
print(f"Executing command: {' '.join(command)}")
# --- Run the command ---
# Use Popen for non-blocking execution or run() for blocking.
# We'll use Popen to show how to read line by line.
try:
# Popen starts the process and immediately returns
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# Read output line by line as it becomes available
while True:
# readline() will block until a full line is received or the process ends
output = process.stdout.readline()
if output == '' and process.poll() is not None:
# The process has finished
break
if output:
print(f"Received: {output.strip()}")
# Check for any errors after the process has finished
stderr = process.stderr.read()
if stderr:
print(f"Error output:\n{stderr}")
except FileNotFoundError:
print("Error: 'mosquitto_sub' command not found.")
print("Please ensure the Mosquitto clients are installed and in your system's PATH.")
except Exception as e:
print(f"An error occurred: {e}")
Step 3: Run the Script
Save the code as call_subscriber.py and run it:
python call_subscriber.py
It will execute the mosquitto_sub command and print any messages it receives to the console. Again, you can test it by publishing messages from another terminal using mosquitto_pub.
Comparison: Method 1 vs. Method 2
| Feature | Method 1: Python Client (paho-mqtt) |
Method 2: subprocess with mosquitto_sub |
|---|---|---|
| Dependencies | Requires paho-mqtt library. |
Requires mosquitto-clients installed on the system. |
| Integration | Excellent. Native Python, easy to integrate with other libraries and logic. | Poor. Requires parsing command-line output, which can be brittle. |
| Performance | High. Runs in the same process, efficient for high-throughput or long-running connections. | Lower. Creates a new process for each call, which has overhead. Not ideal for continuous streams. |
| Features | Full access to MQTT features (last will, retained messages, QoS levels, etc.) via the API. | Limited to the features exposed by the mosquitto_sub command-line flags. |
| Use Case | Recommended for almost all applications. Building robust, integrated MQTT services. | Quick scripts, simple tasks, or when you need a feature specific to the CLI tool. |
Conclusion
For any serious Python application that needs to subscribe
