I’m trying to script a series of commands with bluetoothctl, but it’s a bit tricky in some parts.
So what I have is a laptop with an additional bluetooth dongle since the builtin one isn’t working great, the builtin is the controller that’s always set as the default in bluetoothctl though.
What I want to do in a bash function/script:
bluetoothctl select (external dongle)
bluetoothctl scan on
(wait until a specific headset device is detected)
bluetoothctl pair (headset)
bluetoothctl connect (headset)
bluetoothctl trust (headset)
The main problem with the above is that the scan on command has no “until found” flag, I would like to scan until my headset is found. How would I solve that? I can’t grep the output because bluetoothctl doesn’t finish by itself, i.e. the scan command keeps running in the foreground.
Also the first command where I select the controller doesn’t seem to persist, if I run bluetoothctl select <dongle> and then bluetoothctl list, then the internal controller will still be shown as the default.
I had a similar issue. My solution was to blacklist the internal device in /etc/udev/rules.d/ by creating a file called 90-bluetooth.rules. This file consits only of two lines.
# Intel Bluetooth should be disabled
SUBSYSTEM=="usb", ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0a2a", ATTR{authorized}="0"
You need to replace the vendor and device ID with the actual ones on your system.
This completely disables the built-in device, so only the dongle is used.
WHAT @Trekkie00 SAY
And all other can be done by configuration it does not need scripts to create… but on pulseaudio it will may never get working, i switched to pipewire and if i enable my BT Headset it will get connected automatic.
The problem for me is that I’m switching the usb bt dongle between two computers using a usb peripherals switch, so the dongle is disconnected from the running host daily. This doesn’t work that great, so I found that it’s easiest to just reset everything, even though I am using pipewire.
Not if I can solve it with a simple script and spend no money at all
Mainly I’m wondering how I can somehow grep the bluetoothctl scan on command, so that immediately when my headphones are detected, I can stop and connect. This seems really tricky since bluetoothctl wants to run in the foreground and there are no flags to set for the scan command to look for a specific device.
While it’s true that bluetoothctl is an application with it’s own console I figured you should be able to run bluetoothctl scan on and act on the output, but it does seem tricky to interact with it. I suppose that’s more of a general design issue with bluetoothctl, I wonder if there are any open issues for it to allow a more programmatic approach to using it.
Some examples show that you should be able to just do bluetoothctl -- pair <mac>, but I never found that to work, I always need to scan first and detect the device before the pair command works.
The solution for this is to use the expect utility, it allows one to interact with application consoles, and does exactly what I’m looking for it to do: