For guys who spent most times in a terminal, it makes a lot of sense to be able to connect to your Bluetooth devices such as Speakers, Transmitters and any other electronic devices from the terminal. In this article we’ll discuss how you can control a Bluetooth device from a Linux terminal – Ubuntu, Debian, Fedora and Arch based distributions.

The Bluetooth wireless technology is a worldwide specification for a small-form factor, low-cost radio solution that provides links between mobile computers, mobile phones, other portable handheld devices, and connectivity to the Internet. The specification is developed, published and promoted by the Bluetooth Special Interest Group (SIG).

In this guide, we’ll use BlueZ which provides support for the core Bluetooth layers and protocols. It is flexible, efficient and uses a modular implementation. It has the following key features.

  • Complete modular implementation
  • Symmetric multi processing safe
  • Multithreaded data processing
  • Support for multiple Bluetooth devices
  • Real hardware abstraction
  • Standard socket interface to all layers
  • Device and service level security support

Install BlueZ on Linux

Install BlueZ packages by using any of the following commands that matches your Linux distribution.

----- Ubuntu / Debian -----
$ sudo apt-get -y install bluetooth bluez bluez-tools rfkill

----- Fedora -----
$ sudo dnf -y install bluez bluez-tools

----- Arch Linux / Manjaro -----
$ sudo pacman -S bluez bluez-utils 

This installation provides the bluetoothctl utility. You need to add your account to the lp group if you wish to connect to a bluetooth tether.

sudo usermod -aG lp $USER
newgrp lp

The bluetooth device should be started and enabled.

$ systemctl is-enabled bluetooth.service 
enabled

$ systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
   Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2019-11-30 17:14:12 EAT; 3h 55min ago
     Docs: man:bluetoothd(8)
 Main PID: 1638 (bluetoothd)
    Tasks: 1 (limit: 18590)
   Memory: 2.3M
      CPU: 47ms
   CGroup: /system.slice/bluetooth.service
           └─1638 /usr/libexec/bluetooth/bluetoothd

Nov 30 17:14:12 myfed.example.net systemd[1]: Starting Bluetooth service...
Nov 30 17:14:12 myfed.example.net bluetoothd[1638]: Bluetooth daemon 5.52
Nov 30 17:14:12 myfed.example.net systemd[1]: Started Bluetooth service.
Nov 30 17:14:12 myfed.example.net bluetoothd[1638]: Starting SDP server
Nov 30 17:14:12 myfed.example.net bluetoothd[1638]: Bluetooth management interface 1.14 initialized
Nov 30 21:07:52 myfed.example.net bluetoothd[1638]: Endpoint registered: sender=:1.77 path=/MediaEndpoint/A2DPSink/sbc
Nov 30 21:07:52 myfed.example.net bluetoothd[1638]: Endpoint registered: sender=:1.77 path=/MediaEndpoint/A2DPSource/sbc

How to pair and connect to a Bluetooth device

We’re going to use the bluetoothctl CLI tp configure bluez. If you have an alternative front-end tool such as GNOME Bluetooth, you can use it instead.

First ensure Bluetooth is not disabled.

$ rfkill 
ID TYPE      DEVICE               SOFT          HARD
0 bluetooth tpacpi_bluetooth_sw   blocked       unblocked
1 wlan      phy0                  unblocked     unblocked

If it is blocked, unblock it by using the command below.

$ rfkill unblock 0

Confirm it is unblocked.

$ rfkill          
ID TYPE      DEVICE                   SOFT      HARD
 0 bluetooth tpacpi_bluetooth_sw unblocked unblocked
 1 wlan      phy0                unblocked unblocked
 2 bluetooth hci0                unblocked unblocked

Using bluetoothctl to connect to a Bluetooth device

This is a general outline of pairing a device using bluetoothctl.

  • Start the bluetoothctl interactive command.
$ bluetoothctl
Agent registered

$ bluetoothctl show 
Controller 20:79:18:5E:4B:64 (public)
	Name: myfed.example.net
	Alias: myfed.example.net
	Class: 0x000c010c
	Powered: yes
	Discoverable: no
	DiscoverableTimeout: 0x00000000
	Pairable: no
	UUID: Headset AG                (00001112-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
	UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
	UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
	UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
	UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
	UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
	UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
	Modalias: usb:v1D6Bp0246d0534
	Discovering: no
Advertising Features:
	ActiveInstances: 0x00
	SupportedInstances: 0x05
	SupportedIncludes: tx-power
	SupportedIncludes: appearance
	SupportedIncludes: local-name

Input help to get a list of available commands.

  • Turn on your bluetooth adapter
[bluetooth]# agent KeyboardOnly
Agent is already registered

[bluetooth]# default-agent
Default agent request successful

[bluetooth]# power on
Changing power on succeeded
  • Do a scan to detect your Bluetooth devices
# scan on
Discovery started
[CHG] Controller 20:79:18:5E:4B:64 Discovering: yes
[NEW] Device 14:AB:C5:CC:C7:AB 14-AB-C5-CC-C7-AB
[CHG] Device 14:AB:C5:CC:C7:AB TxPower: 8
[CHG] Device 14:AB:C5:CC:C7:AB Name: DESKTOP-N9GVMQ2
[CHG] Device 14:AB:C5:CC:C7:AB Alias: DESKTOP-N9GVMQ2
[CHG] Device 14:AB:C5:CC:C7:AB UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 14:AB:C5:CC:C7:AB UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
[CHG] Device 14:AB:C5:CC:C7:AB UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device 14:AB:C5:CC:C7:AB UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 14:AB:C5:CC:C7:AB UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[NEW] Device 5C:FB:7C:A4:13:C6 JBL Clip 3
  • Pair with discovered bluetooth device
[bluetooth]# pair 5C:FB:7C:A4:13:C6
Attempting to pair with 5C:FB:7C:A4:13:C6
[CHG] Device 5C:FB:7C:A4:13:C6 Connected: yes
[CHG] Device 5C:FB:7C:A4:13:C6 UUIDs: 00001108-0000-1000-8000-00805f9b34fb
[CHG] Device 5C:FB:7C:A4:13:C6 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device 5C:FB:7C:A4:13:C6 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 5C:FB:7C:A4:13:C6 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device 5C:FB:7C:A4:13:C6 UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device 5C:FB:7C:A4:13:C6 ServicesResolved: yes
[CHG] Device 5C:FB:7C:A4:13:C6 Paired: yes
Pairing successful

# trust 5C:FB:7C:A4:13:C6
[CHG] Device 5C:FB:7C:A4:13:C6 Trusted: yes
Changing 5C:FB:7C:A4:13:C6 trust succeeded

# paired-devices
Device 5C:FB:7C:A4:13:C6 JBL Clip 3

# devices
Device 5C:FB:7C:A4:13:C6 JBL Clip 3
  • Connect to device after pairing
[bluetooth]# connect 5C:FB:7C:A4:13:C6
Attempting to connect to 5C:FB:7C:A4:13:C6
[CHG] Device 5C:FB:7C:A4:13:C6 Connected: yes
Connection successful

[JBL Clip 3]# info
Device 5C:FB:7C:A4:13:C6 (public)
	Name: JBL Clip 3
	Alias: JBL Clip 3
	Class: 0x00200414
	Icon: audio-card
	Paired: yes
	Trusted: yes
	Blocked: no
	Connected: yes
	LegacyPairing: no
	UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
	UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
	UUID: Handsfree                 (0000111e-0000-1000-8000-00805f9b34fb)
	ManufacturerData Key: 0x0057
	ManufacturerData Value:
  01 00 cb 0e d0 1e 03 01                          ........        
	RSSI: -21
	TxPower: 0

Power on Bluetooth Adapter at Power on

To power on your Bluetooth adapter at system startup, open the configuration file.

$ sudo vim /etc/bluetooth/main.conf

Add the line AutoEnable=true

[Policy]
AutoEnable=true

Reference: