Skip to content

Instantly share code, notes, and snippets.

@Krutonium
Created May 24, 2025 01:58
Show Gist options
  • Save Krutonium/7c5dabfb601341ac2b5f9186e2948d95 to your computer and use it in GitHub Desktop.
Save Krutonium/7c5dabfb601341ac2b5f9186e2948d95 to your computer and use it in GitHub Desktop.
#!/usr/bin/env nix-shell
#! nix-shell -i bash
#! nix-shell -p bash lshw
convert_bus_id() {
local raw="${1#*@}" # remove pci@
IFS=':.'
read -r domain bus slot func <<< "$raw"
echo "PCI:$((16#$bus)):$((16#$slot)):$((16#$func))"
}
# Parse blocks using awk and extract fields
lshw -c display 2>/dev/null | awk '
BEGIN { RS="*-display"; }
/bus info:/ {
# Reset vars
bus=""; driver=""; product=""
# Read block line by line
n = split($0, lines, "\n")
for (i = 1; i <= n; ++i) {
line = lines[i]
if (match(line, /bus info: pci@([0-9a-f:.]+)/, m)) {
bus = m[1]
}
if (match(line, /configuration:.*driver=([^ ]+)/, m)) {
driver = m[1]
}
if (match(line, /product:[ \t]*(.+)/, m)) {
product = tolower(m[1])
}
}
if (bus != "") {
printf("BUS:%s DRIVER:%s PRODUCT:%s\n", bus, driver, product)
}
}' | while IFS= read -r line; do
bus=$(echo "$line" | sed -n 's/.*BUS:\([^ ]*\).*/\1/p')
driver=$(echo "$line" | sed -n 's/.*DRIVER:\([^ ]*\).*/\1/p')
product=$(echo "$line" | sed -n 's/.*PRODUCT:\(.*\)/\1/p')
pci_formatted=$(convert_bus_id "$bus")
case "$driver" in
i915)
echo "intelBusId = \"$pci_formatted\";"
;;
nvidia|nouveau)
echo "nvidiaBusId = \"$pci_formatted\";"
;;
amdgpu|radeon)
echo "amdBusId = \"$pci_formatted\";"
;;
*)
echo "Unknown display device (product='$product', driver='$driver') with bus $pci_formatted"
;;
esac
done
@Krutonium
Copy link
Author

Should return along the lines of:

nvidiaBusId = "PCI:1:0:0";
intelBusId = "PCI:0:2:0";

Which is perfect for NixOS; specifically when you're doing Prime setup on Laptops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment