Skip to content

Instantly share code, notes, and snippets.

@jbazik
Last active June 10, 2021 19:07
Show Gist options
  • Save jbazik/d5dc0d0be25d1769027abbc3f049cbb2 to your computer and use it in GitHub Desktop.
Save jbazik/d5dc0d0be25d1769027abbc3f049cbb2 to your computer and use it in GitHub Desktop.
A parsable alternative to nvidia-detect
#!/bin/sh
#
# Copyright (C) 2021 John Bazik <me@johnbazik.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see http://www.gnu.org/licenses/.
usage() {
cat <<-EOF
usage: nvidia-driver [PCIID]..
-a, --all list all devices and driver versions
-h, --help print this message
-n, --numver just show driver major version number
EOF
exit $1
}
fail() {
echo "$@" >&2
exit 1
}
devices=''
while [ $# -gt 0 ]; do
case "$1" in
-a|--all) all=1;;
-h|--help) usage 0;;
-n|--numver) numver=1;;
-*) usage 1;;
*) devices="$devices $1";;
esac
shift
done
idlistdir=/usr/share/nvidia
[ -d $idlistdir ] || fail "$idlistdir: pci id lists not found"
curidlist=$idlistdir/nvidia.ids
[ -f $curidlist ] || fail "$curidlist: current id list not found"
curidlistsum=$(sum $curidlist)
command -v lspci >/dev/null || fail "lspci: command not found"
if [ "$devices" ]; then
for device in $devices; do
device=$(echo $device | tr a-z A-Z)
case $device in
10DE????) echo $device;;
12D2????) echo $device;;
????) echo 10DE$device;;
*) fail "Error parsing PCI ID [$device]";;
esac
done
else
#
# Find nvidia devices
#
lspci -mn |
awk '{gsub("\"","");
if (($2 ~ "030[0-2]") && ($3 == "10de" || $3 == "12d2"))
{print toupper($3) toupper($4)}}' |
sort -u
fi |
while read device; do
echo -n "$device "
ls $idlistdir/nvidia-*[0-9]*.ids |
{
while read idlist; do
if grep -q $device $idlist; then
name=$(basename $idlist .ids)
nver=$(echo $name | sed 's/[^0-9]*\([0-9]\+\).*/\1/')
#
# if idlist is identical to nvidia.ids, then use current driver
#
if [ "$(sum $idlist)" = "$curidlistsum" ]; then
pkg=nvidia-driver
else
#
# handle architecture if present
#
case ${name##*-} in
[0-9]*) arch='';;
*) arch=${name##*-}; name=${name%-$arch}; arch=:$arch;;
esac
pkg=$name-driver$arch
fi
#
# prepend actual version for sorting
#
if [ "$numver" ]; then
printf "%03d%d\n" $nver $nver
else
printf "%03d%s\n" $nver $pkg
fi
fi
done
#
# Print none or 0 if there was no match
#
[ "$pkg" ] || { [ "$numver" ] && echo 0000 || echo 000none; }
} | sort -Vru | cut -c4- |
if [ "$all" ]; then
tr "\n" " "
echo
else
head -n1
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment