Bluetooth CLI (bluetoothctl)
Quick Reference
# Connect first paired device
bluetoothctl connect $(bluetoothctl paired-devices | awk '{print $2}' | head -1)
# Connect by name pattern
bluetoothctl connect $(bluetoothctl devices | awk '/Adv360/{print $2}')
# Status
bluetoothctl devices Connected
Controller Operations
# List controllers
bluetoothctl list
# Show controller info
bluetoothctl show
# Power on/off
bluetoothctl power on
bluetoothctl power off
# Make discoverable (for pairing FROM another device)
bluetoothctl discoverable on
Device Discovery
# Scan for devices (15 second timeout)
timeout 15 bluetoothctl scan on
# List all discovered devices
bluetoothctl devices
# List only paired devices
bluetoothctl paired-devices
# List only connected devices
bluetoothctl devices Connected
Connection Management
# Connect to device
bluetoothctl connect XX:XX:XX:XX:XX:XX
# Disconnect
bluetoothctl disconnect XX:XX:XX:XX:XX:XX
# Show device info
bluetoothctl info XX:XX:XX:XX:XX:XX
Pairing Workflow
# Full pairing workflow (one-time setup)
bluetoothctl scan on # Find device
bluetoothctl pair XX:XX:XX:XX:XX # Pair (may prompt for PIN)
bluetoothctl trust XX:XX:XX:XX:XX # Enable auto-connect
bluetoothctl connect XX:XX:XX:XX # Connect now
# Remove pairing
bluetoothctl remove XX:XX:XX:XX:XX
One-Liners
# Connect first paired device
bluetoothctl connect $(bluetoothctl paired-devices | awk '{print $2}' | head -1)
# Connect by name pattern (e.g., "Adv360", "Sony", "AirPods")
bluetoothctl connect $(bluetoothctl devices | awk '/Adv360/{print $2}')
# Connect ALL paired devices
bluetoothctl paired-devices | awk '{print $2}' | xargs -I{} bluetoothctl connect {}
# Disconnect all
bluetoothctl devices Connected | awk '{print $2}' | xargs -I{} bluetoothctl disconnect {}
# Battery level (if supported)
bluetoothctl info | awk '/Battery/'
# Reconnect cycle (troubleshooting)
MAC="XX:XX:XX:XX:XX:XX"; bluetoothctl disconnect $MAC && sleep 2 && bluetoothctl connect $MAC
Recommended Aliases
Add to ~/.zshrc:
# Connect by name pattern: btc Adv360, btc Sony
btc() { bluetoothctl connect $(bluetoothctl devices | awk "/$1/{print \$2}"); }
# Connect first paired device (fastest emergency command)
alias bt1='bluetoothctl connect $(bluetoothctl paired-devices | awk "{print \$2}" | head -1)'
# Connect all paired devices
alias btall='bluetoothctl paired-devices | awk "{print \$2}" | xargs -I{} bluetoothctl connect {}'
# Status: what's connected + battery
alias bts='bluetoothctl devices Connected && bluetoothctl info 2>/dev/null | awk "/Name|Battery/"'
# Scan for new devices (15s timeout)
alias btscan='timeout 15 bluetoothctl scan on'
# Disconnect all
alias btoff='bluetoothctl devices Connected | awk "{print \$2}" | xargs -I{} bluetoothctl disconnect {}'
Troubleshooting
# Check controller is powered
bluetoothctl show | grep Powered
# Check service status
systemctl status bluetooth
# Restart Bluetooth service
sudo systemctl restart bluetooth
# Check kernel module loaded
lsmod | grep btusb
# Kernel messages
dmesg | grep -i bluetooth | tail -20
# D-Bus introspection (advanced)
busctl tree org.bluez
Audio Devices
# Check PipeWire sees device
wpctl status
# Check PulseAudio sees device
pactl list cards short
# Set default sink to Bluetooth device
wpctl set-default $(wpctl status | awk '/bluez/{print $1}' | head -1)
Architecture
User Space: bluetoothctl ──► D-Bus ──► bluetoothd (BlueZ daemon)
│
Kernel: btusb module
│
Hardware: Bluetooth Controller
Key paths:
-
Service:
systemctl status bluetooth -
Config:
/etc/bluetooth/main.conf -
Device cache:
/var/lib/bluetooth/<adapter>/<device>/